Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ethereum_spec_tools/evm_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def main(
in_file = sys.stdin

if options.evm_tool == "t8n":
t8n_tool = T8N(options, out_file, in_file)
t8n_tool = T8N(options, in_file, out_file)
return t8n_tool.run()
elif options.evm_tool == "b11r":
b11r_tool = B11R(options, out_file, in_file)
Expand Down
2 changes: 1 addition & 1 deletion src/ethereum_spec_tools/evm_tools/statetest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def run_test_case(
if output_basedir is not None:
t8n_options.output_basedir = output_basedir

t8n = T8N(t8n_options, out_stream, in_stream)
t8n = T8N(t8n_options, in_stream, out_stream)
t8n.run_state_test()
return t8n.result

Expand Down
70 changes: 67 additions & 3 deletions src/ethereum_spec_tools/evm_tools/t8n/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@
import json
import os
from functools import partial
from typing import Any, TextIO
from typing import Any, Optional, TextIO, Union

from ethereum_rlp import rlp
from ethereum_types.numeric import U64, U256, Uint

from ethereum import trace
from ethereum.exceptions import EthereumException, InvalidBlock
from ethereum_clis.types import TransitionToolRequest
from ethereum_spec_tools.forks import Hardfork
from ethereum_clis.types import TransitionToolOutput
from ethereum_clis.clis.execution_specs import ExecutionSpecsExceptionMapper

from ..loaders.fixture_loader import Load
from ..loaders.fork_loader import ForkLoad
from ..utils import (
FatalException,
get_module_name,
get_module_name_json_input,
get_stream_logger,
parse_hex_or_int,
)
Expand Down Expand Up @@ -80,13 +84,59 @@ class T8N(Load):
"""The class that carries out the transition"""

def __init__(
self, options: Any, out_file: TextIO, in_file: TextIO
self,
options: Any,
in_file: Union[TransitionToolRequest, TextIO],
out_file: Optional[TextIO] = None
) -> None:
self.out_file = out_file
self.in_file = in_file
self.options = options
self.forks = Hardfork.discover()

if isinstance(in_file, TransitionToolRequest):
self._init_from_pydantic(options, in_file)
else:
if out_file is None:
raise ValueError("out_file is required for JSON file input")
self._init_from_json(options, in_file, out_file)

def _init_from_pydantic(self, options: Any, in_file: TransitionToolRequest) -> None:
fork_module, self.fork_block = get_module_name(
self.forks, options, in_file.input.env
)
self.fork = ForkLoad(fork_module)
self.exception_mapper = ExecutionSpecsExceptionMapper()

if options.trace:
trace_memory = getattr(options, "trace.memory", False)
trace_stack = not getattr(options, "trace.nostack", False)
trace_return_data = getattr(options, "trace.returndata")
trace.set_evm_trace(
partial(
evm_trace,
trace_memory=trace_memory,
trace_stack=trace_stack,
trace_return_data=trace_return_data,
output_basedir=options.output_basedir,
)
)
self.logger = get_stream_logger("T8N")

super().__init__(
options.state_fork,
fork_module,
)

self.chain_id = parse_hex_or_int(options.state_chainid, U64)
self.alloc = Alloc(self, in_file.input.alloc)
self.env = Env(self, in_file.input.env)
self.txs = Txs(self, in_file.input.txs)
self.result = Result(
self.env.block_difficulty, self.env.base_fee_per_gas
)

def _init_from_json(self, options: Any, in_file: TextIO, out_file: TextIO) -> None:
if "stdin" in (
options.input_env,
options.input_alloc,
Expand All @@ -96,7 +146,7 @@ def __init__(
else:
stdin = None

fork_module, self.fork_block = get_module_name(
fork_module, self.fork_block = get_module_name_json_input(
self.forks, self.options, stdin
)
self.fork = ForkLoad(fork_module)
Expand Down Expand Up @@ -311,7 +361,21 @@ def run(self) -> int:

json_state = self.alloc.to_json()
json_result = self.result.to_json()
if isinstance(self.in_file, TransitionToolRequest):
json_output = {}

txs_rlp = "0x" + rlp.encode(self.txs.all_txs).hex()
json_output["body"] = txs_rlp
json_output["alloc"] = json_state
json_output["result"] = json_result
output: TransitionToolOutput = TransitionToolOutput.model_validate(
json_output, context={"exception_mapper": self.exception_mapper}
)
return output
else:
return self._write_json_output(json_state, json_result)

def _write_json_output(self, json_state: Any, json_result: Any) -> int:
json_output = {}

if self.options.output_body == "stdout":
Expand Down
Loading