427 const auto& val =
memory.get(src_addr);
464 result = MemoryValue::from<FF>(
context.get_address());
467 result = MemoryValue::from<FF>(
context.get_msg_sender());
470 result = MemoryValue::from<FF>(
context.get_transaction_fee());
473 result = MemoryValue::from<FF>(
context.get_globals().chain_id);
476 result = MemoryValue::from<FF>(
context.get_globals().version);
479 result = MemoryValue::from<uint32_t>(
context.get_globals().block_number);
482 result = MemoryValue::from<uint64_t>(
context.get_globals().timestamp);
485 result = MemoryValue::from<uint128_t>(
context.get_globals().gas_fees.fee_per_l2_gas);
488 result = MemoryValue::from<uint128_t>(
context.get_globals().gas_fees.fee_per_da_gas);
491 result = MemoryValue::from<uint1_t>(
context.get_is_static() ? 1 : 0);
494 result = MemoryValue::from<uint32_t>(
context.gas_left().l2_gas);
497 result = MemoryValue::from<uint32_t>(
context.gas_left().da_gas);
586 const auto& allocated_l2_gas_read =
memory.get(l2_gas_offset);
587 const auto& allocated_da_gas_read =
memory.get(da_gas_offset);
590 const auto& cd_size =
memory.get(cd_size_offset);
596 Gas{ .
l2_gas = allocated_l2_gas_read.as<uint32_t>(), .
da_gas = allocated_da_gas_read.as<uint32_t>() });
604 cd_size.as<uint32_t>(),
646 const auto& allocated_l2_gas_read =
memory.get(l2_gas_offset);
647 const auto& allocated_da_gas_read =
memory.get(da_gas_offset);
650 const auto& cd_size =
memory.get(cd_size_offset);
656 Gas{ .
l2_gas = allocated_l2_gas_read.as<uint32_t>(), .
da_gas = allocated_da_gas_read.as<uint32_t>() });
664 cd_size.as<uint32_t>(),
697 const auto& cd_copy_size =
memory.get(cd_size_offset);
733 const auto& rd_copy_size =
memory.get(rd_size_offset);
734 const auto& rd_offset_read =
memory.get(rd_offset);
792 .rd_size =
rd_size.as<uint32_t>(),
793 .gas_used =
context.get_gas_used(),
795 .halting_pc =
context.get_pc(),
819 const auto& rev_size =
memory.get(rev_size_offset);
825 .rd_size = rev_size.as<uint32_t>(),
826 .gas_used =
context.get_gas_used(),
828 .halting_pc =
context.get_pc(),
829 .halting_message =
"Assertion failed: " });
869 const auto& resolved_cond =
memory.get(cond_addr);
894 auto& internal_call_stack_manager =
context.get_internal_call_stack_manager();
896 internal_call_stack_manager.push(
context.get_pc(),
context.get_next_pc());
914 auto& internal_call_stack_manager =
context.get_internal_call_stack_manager();
916 auto next_pc = internal_call_stack_manager.pop();
1167 uint32_t da_gas_factor =
static_cast<uint32_t
>(!was_slot_written_before);
1170 if (
context.get_is_static()) {
1172 "SSTORE: Static call cannot update the state. Cannot write to storage in static context");
1175 if (!was_slot_written_before &&
1207 const auto& unique_note_hash =
memory.get(unique_note_hash_addr);
1208 const auto& leaf_index =
memory.get(leaf_index_addr);
1213 uint64_t leaf_index_value = leaf_index.as<uint64_t>();
1219 if (index_in_range) {
1222 value = MemoryValue::from<uint1_t>(0);
1264 memory.set(exists_offset, result);
1293 if (
context.get_is_static()) {
1295 "EMITNULLIFIER: Static call cannot update the state. Cannot emit nullifier in static context");
1337 const auto& address_value =
memory.get(address_offset);
1379 if (
context.get_is_static()) {
1381 "EMITNOTEHASH: Static call cannot update the state. Cannot emit note hash in static context");
1415 const auto& msg_hash =
memory.get(msg_hash_addr);
1416 const auto& leaf_index =
memory.get(leaf_index_addr);
1421 uint64_t leaf_index_value = leaf_index.as<uint64_t>();
1427 if (index_in_range) {
1430 value = MemoryValue::from<uint1_t>(0);
1500 const auto& p_x =
memory.get(p_x_addr);
1501 const auto& p_y =
memory.get(p_y_addr);
1502 const auto& p_inf =
memory.get(p_inf_addr);
1504 const auto& q_x =
memory.get(q_x_addr);
1505 const auto& q_y =
memory.get(q_y_addr);
1506 const auto& q_inf =
memory.get(q_inf_addr);
1559 const auto& radix =
memory.get(radix_addr);
1560 const auto& num_limbs =
memory.get(num_limbs_addr);
1565 BB_BENCH_NAME(
"Execution::to_radix_be::set_and_validate_inputs");
1581 uint32_t radix_value = radix.as<uint32_t>();
1582 uint32_t num_p_limbs =
greater_than.
gt(radix.as<uint32_t>(), 256)
1597 radix.as<uint32_t>(),
1598 num_limbs.as<uint32_t>(),
1628 const auto& log_size =
memory.get(log_size_offset);
1630 uint32_t log_size_int = log_size.as<uint32_t>();
1670 if (
context.get_is_static()) {
1672 "SENDL2TOL1MSG: Static call cannot update the state. Cannot send L2 to L1 message in static context");
1708 sha256.compression(
context.get_memory(), state_addr, input_addr, output_addr);
1730 enqueued_call_context->get_is_static(),
1731 enqueued_call_context->get_gas_limit());
1756 const auto before_context_event =
context.serialize_context_event();
1758 const auto pc =
context.get_pc();
1766 context.get_bytecode_manager().get_bytecode_id();
1792 vinfo(
"Bytecode retrieval error:: ", e.what());
1796 vinfo(
"Instruction fetching error: ", e.what());
1800 vinfo(
"Addressing exception: ", e.what());
1804 vinfo(
"Register validation exception: ", e.what());
1808 vinfo(
"Out of gas exception: ", e.what());
1812 vinfo(
"Opcode execution exception: ", e.what());
1815 }
catch (
const std::exception& e) {
1818 important(
"An unhandled exception occurred: ", e.what());
1832 .next_context_id = next_context_id,
1833 .addressing_event = addressing_event,
1834 .before_context_event = before_context_event,
1835 .after_context_event =
context.serialize_context_event(),
1868 child_context->get_is_static(),
1869 child_context->get_gas_limit());
1872 BB_ASSERT(parent_bytecode_id.has_value(),
1873 "Bytecode should have been retrieved in the parent context if it issued a call");
1878 .entered_context_id = child_context->get_context_id(),
1882 .bytecode_id = parent_bytecode_id.value(),
1894 .numUnencryptedLogFields = side_effects.get_num_unencrypted_log_fields(),
1895 .numL2ToL1Messages =
static_cast<uint32_t
>(side_effects.l2_to_l1_messages.size()),
1936 parent_context.set_last_rd_addr(result.
rd_offset);
1937 parent_context.set_last_rd_size(result.
rd_size);
1938 parent_context.set_last_success(result.
success);
1940 parent_context.set_gas_used(result.
gas_used + parent_context.get_gas_used());
1941 parent_context.set_child_context(
std::move(child_context));
1943 BB_ASSERT_EQ(parent_context.get_checkpoint_id_at_creation(),
1945 "Checkpoint id mismatch: gone back to the wrong db/context");
1964 .gas_used =
context.get_gas_used(),
1966 .halting_pc =
context.get_pc(),
1967 .halting_message = halting_message,
1985 debug(
"Dispatching opcode: ", opcode,
" (",
static_cast<uint32_t
>(opcode),
")");
2127 throw std::runtime_error(
"Tried to dispatch unknown execution opcode: " +
2141template <
typename... Ts>
2144 const
std::vector<
Operand>& resolved_operands)
2147 BB_ASSERT_DEBUG(resolved_operands.size() ==
sizeof...(Ts),
"Resolved operands size mismatch");
2151 auto convert_operand = []<
typename T>(
const Operand& op) -> T {
2175 for (
size_t i = 0; i < register_info.num_inputs(); i++) {
2176 if (register_info.expected_tag(i) && register_info.expected_tag(i) != this->inputs.at(i).get_tag()) {
2181 " does not match expected tag ",
2197 BB_ASSERT_DEBUG(register_info.num_outputs() == 1,
"Outputs size mismatch");
#define BB_ASSERT(expression,...)
#define BB_ASSERT_DEBUG(expression,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define NOTE_HASH_TREE_LEAF_COUNT
#define L1_TO_L2_MSG_TREE_LEAF_COUNT
#define MAX_L2_TO_L1_MSGS_PER_TX
#define MAX_NOTE_HASHES_PER_TX
#define MAX_NULLIFIERS_PER_TX
#define MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX
#define BB_BENCH_NAME(name)
static TaggedValue from_tag(ValueTag tag, FF value)
virtual std::optional< BytecodeId > get_retrieved_bytecode_id()=0
virtual const AztecAddress & get_msg_sender() const =0
virtual Gas get_parent_gas_limit() const =0
virtual PC get_pc() const =0
virtual InternalCallStackManagerInterface & get_internal_call_stack_manager()=0
virtual uint32_t get_parent_cd_size() const =0
virtual SideEffectTrackerInterface & get_side_effect_tracker()=0
virtual MemoryAddress get_parent_cd_addr() const =0
virtual AppendOnlyTreeSnapshot get_written_public_data_slots_tree_snapshot()=0
virtual PC get_next_pc() const =0
virtual uint32_t get_parent_id() const =0
virtual bool get_is_static() const =0
virtual BytecodeManagerInterface & get_bytecode_manager()=0
virtual const AztecAddress & get_address() const =0
virtual uint32_t get_context_id() const =0
virtual Gas get_parent_gas_used() const =0
virtual std::unique_ptr< ContextInterface > make_nested_context(const AztecAddress &address, const AztecAddress &msg_sender, const FF &transaction_fee, ContextInterface &parent_context, MemoryAddress cd_offset_address, uint32_t cd_size, bool is_static, const Gas &gas_limit, TransactionPhase phase)=0
virtual uint32_t get_next_context_id() const =0
virtual void debug_log(MemoryInterface &memory, AztecAddress contract_address, MemoryAddress level_offset, MemoryAddress message_offset, uint16_t message_size, MemoryAddress fields_offset, MemoryAddress fields_size_offset)=0
virtual EmbeddedCurvePoint add(const EmbeddedCurvePoint &p, const EmbeddedCurvePoint &q)=0
virtual void emit_unencrypted_log(MemoryInterface &memory, ContextInterface &context, const AztecAddress &contract_address, MemoryAddress log_offset, uint32_t log_size)=0
virtual std::unique_ptr< GasTrackerInterface > make_gas_tracker(GasEvent &gas_event, const Instruction &instruction, ContextInterface &context)=0
virtual std::unique_ptr< AddressingInterface > make_addressing(AddressingEvent &event)=0
void lt(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
LT execution opcode handler: Check if the first value is less than the second.
void emit_note_hash(ContextInterface &context, MemoryAddress note_hash_addr)
EMITNOTEHASH execution opcode handler: Emit a note hash to the note hash tree.
std::vector< MemoryValue > inputs
void mov(ContextInterface &context, MemoryAddress src_addr, MemoryAddress dst_addr)
MOV execution opcode handler: Move a memory value from one memory location to another.
void static_call(ContextInterface &context, MemoryAddress l2_gas_offset, MemoryAddress da_gas_offset, MemoryAddress addr, MemoryAddress cd_size_offset, MemoryAddress cd_offset)
STATICCALL execution opcode handler: Call a contract in a static context. Creates a new (nested) exec...
void debug_log(ContextInterface &context, MemoryAddress level_offset, MemoryAddress message_offset, MemoryAddress fields_offset, MemoryAddress fields_size_offset, uint16_t message_size)
DEBUGLOG execution opcode handler: Log a debug message. Logs a debug message to the debug logger if t...
EventEmitterInterface< ExecutionEvent > & events
void cd_copy(ContextInterface &context, MemoryAddress cd_size_offset, MemoryAddress cd_offset, MemoryAddress dst_addr)
CALLDATACOPY execution opcode handler: Copy calldata from the parent context to the current context....
std::unique_ptr< GasTrackerInterface > gas_tracker
void send_l2_to_l1_msg(ContextInterface &context, MemoryAddress recipient_addr, MemoryAddress content_addr)
SENDL2TOL1MSG execution opcode handler: Send a L2 to L1 message.
void dispatch_opcode(ExecutionOpCode opcode, ContextInterface &context, const std::vector< Operand > &resolved_operands)
Dispatch an opcode. This is the main function that dispatches the opcode to the appropriate handler.
void set_execution_result(const ExecutionResult &exec_result)
ExecutionComponentsProviderInterface & execution_components
void cast(ContextInterface &context, MemoryAddress src_addr, MemoryAddress dst_addr, MemoryTag dst_tag)
CAST execution opcode handler: Cast a value to a different tag.
void sstore(ContextInterface &context, MemoryAddress src_addr, MemoryAddress slot_addr)
SSTORE execution opcode handler: Store a value in the public data tree.
const std::vector< MemoryValue > & get_inputs() const
void internal_return(ContextInterface &context)
INTERNALRETURN execution opcode handler: Return from a function in the current context....
void set_output(ExecutionOpCode opcode, const MemoryValue &output)
Set the output register.
void get_env_var(ContextInterface &context, MemoryAddress dst_addr, uint8_t env_var_value)
GETENVVAR execution opcode handler: Get the value of an environment variable.
virtual GasTrackerInterface & get_gas_tracker()
void poseidon2_permutation(ContextInterface &context, MemoryAddress src_addr, MemoryAddress dst_addr)
POSEIDON2PERMUTATION execution opcode handler: Perform a Poseidon2 permutation on the input value....
void success_copy(ContextInterface &context, MemoryAddress dst_addr)
SUCCESSCOPY execution opcode handler: Copy the success flag to the destination memory location.
void fdiv(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
FDIV execution opcode handler: Divide two field values.
void jumpi(ContextInterface &context, MemoryAddress cond_addr, uint32_t loc)
JUMPI execution opcode handler: Jump to a new program counter conditionally. Next instruction will be...
void sub(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
SUB execution opcode handler: Subtract two values.
CallStackMetadataCollectorInterface & call_stack_metadata_collector
void rd_copy(ContextInterface &context, MemoryAddress rd_size_offset, MemoryAddress rd_offset, MemoryAddress dst_addr)
RETURNDATACOPY execution opcode handler: Copy return data from the current context to the parent cont...
void l1_to_l2_message_exists(ContextInterface &context, MemoryAddress msg_hash_addr, MemoryAddress leaf_index_addr, MemoryAddress dst_addr)
L1TOL2MSGEXISTS execution opcode handler: Check if a L2 to L1 message exists in the L1 to L2 message ...
void emit_unencrypted_log(ContextInterface &context, MemoryAddress log_size_offset, MemoryAddress log_offset)
EMITUNENCRYPTEDLOG execution opcode handler: Emit an unencrypted log.
void div(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
DIV execution opcode handler: Divide two values.
void emit_nullifier(ContextInterface &context, MemoryAddress nullifier_addr)
EMITNULLIFIER execution opcode handler: Emit a nullifier to the nullifier tree.
EventEmitterInterface< ContextStackEvent > & ctx_stack_events
const MemoryValue & get_output() const
void ecc_add(ContextInterface &context, MemoryAddress p_x_addr, MemoryAddress p_y_addr, MemoryAddress p_inf_addr, MemoryAddress q_x_addr, MemoryAddress q_y_addr, MemoryAddress q_inf_addr, MemoryAddress dst_addr)
ECADD execution opcode handler: Perform an elliptic curve addition and write the result to the destin...
void keccak_permutation(ContextInterface &context, MemoryAddress dst_addr, MemoryAddress src_addr)
KECCAKF1600 execution opcode handler: Perform a Keccak permutation on the data.
void jump(ContextInterface &context, uint32_t loc)
JUMP execution opcode handler: Jump to a new program counter. Next instruction will be executed at th...
const ExecutionResult & get_execution_result() const
void sha256_compression(ContextInterface &context, MemoryAddress output_addr, MemoryAddress state_addr, MemoryAddress input_addr)
SHA256COMPRESSION execution opcode handler: Perform a SHA256 compression on the input and state value...
void sload(ContextInterface &context, MemoryAddress slot_addr, MemoryAddress dst_addr)
SLOAD execution opcode handler: Load a value from the public data tree. Loads a value from the public...
void ret(ContextInterface &context, MemoryAddress ret_size_offset, MemoryAddress ret_offset)
RETURN execution opcode handler: Return from a contract. Sets the execution result to the return data...
void internal_call(ContextInterface &context, uint32_t loc)
INTERNALCALL execution opcode handler: Call a function in the current context. Pushes the current pro...
EccInterface & embedded_curve
CancellationTokenPtr cancellation_token_
void op_not(ContextInterface &context, MemoryAddress src_addr, MemoryAddress dst_addr)
NOT execution opcode handler: Perform bitwise NOT operation on a value.
void shl(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
SHL execution opcode handler: Perform left shift operation on a value.
void handle_enter_call(ContextInterface &parent_context, std::unique_ptr< ContextInterface > child_context)
Handle the entering of a call. This is called when a call is made from a context. This is a helper fu...
void nullifier_exists(ContextInterface &context, MemoryAddress nullifier_offset, MemoryAddress address_offset, MemoryAddress exists_offset)
NULLIFIEREXISTS execution opcode handler: Check if a nullifier exists in the nullifier tree.
void handle_exceptional_halt(ContextInterface &context, const std::string &halting_message)
Handle the exceptional halt of a context. This is called when an exception is thrown during the execu...
void note_hash_exists(ContextInterface &context, MemoryAddress unique_note_hash_addr, MemoryAddress leaf_index_addr, MemoryAddress dst_addr)
NOTEHASHEXISTS execution opcode handler: Check if a note hash exists in the note hash tree at the spe...
ContextProviderInterface & context_provider
void to_radix_be(ContextInterface &context, MemoryAddress value_addr, MemoryAddress radix_addr, MemoryAddress num_limbs_addr, MemoryAddress is_output_bits_addr, MemoryAddress dst_addr)
TORADIXBE execution opcode handler: Convert a value to a radix-based representation....
EmitUnencryptedLogInterface & emit_unencrypted_log_component
void eq(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
EQ execution opcode handler: Check if two values are equal.
void call(ContextInterface &context, MemoryAddress l2_gas_offset, MemoryAddress da_gas_offset, MemoryAddress addr, MemoryAddress cd_size_offset, MemoryAddress cd_offset)
CALL execution opcode handler: Call a contract. Creates a new (nested) execution context and triggers...
std::stack< std::unique_ptr< ContextInterface > > external_call_stack
void handle_exit_call()
Handle the exiting of a call. This is called when a call returns, reverts or errors.
GreaterThanInterface & greater_than
void revert(ContextInterface &context, MemoryAddress rev_size_offset, MemoryAddress rev_offset)
REVERT execution opcode handler: Revert from a contract. Sets the execution result to the revert data...
void rd_size(ContextInterface &context, MemoryAddress dst_addr)
RETURNDATASIZE execution opcode handler: Get the size of the return data.
void mul(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
MUL execution opcode handler: Multiply two values.
void or_op(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
OR execution opcode handler: Perform a bitwise OR operation on the two input values.
void shr(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
SHR execution opcode handler: Perform right shift operation on a value.
DebugLoggerInterface & debug_log_component
void xor_op(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
XOR execution opcode handler: Perform a bitwise XOR operation on the two input values.
void get_contract_instance(ContextInterface &context, MemoryAddress address_offset, MemoryAddress dst_offset, uint8_t member_enum)
GETCONTRACTINSTANCE execution opcode handler: Get a contract instance. Gets a contract instance from ...
GetContractInstanceInterface & get_contract_instance_component
void set_and_validate_inputs(ExecutionOpCode opcode, const std::vector< MemoryValue > &inputs)
Set the register inputs and validate the tags. The tag information is taken from the instruction info...
void lte(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
LTE execution opcode handler: Check if the first value is less than or equal to the second.
const InstructionInfoDBInterface & instruction_info_db
HighLevelMerkleDBInterface & merkle_db
void and_op(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
AND execution opcode handler: Perform a bitwise AND operation on the two input values.
EnqueuedCallResult execute(std::unique_ptr< ContextInterface > enqueued_call_context) override
Execute a top-level enqueued call.
ExecutionIdManagerInterface & execution_id_manager
void set(ContextInterface &context, MemoryAddress dst_addr, MemoryTag tag, const FF &value)
SET execution opcode handler: Set the value at a memory location. If the value does not fit in the ta...
void add(ContextInterface &context, MemoryAddress a_addr, MemoryAddress b_addr, MemoryAddress dst_addr)
ADD execution opcode handler: Add two values.
void call_with_operands(void(Execution::*f)(ContextInterface &, Ts...), ContextInterface &context, const std::vector< Operand > &resolved_operands)
Call with operands. This is a template magic function to dispatch the opcode by deducing the number o...
virtual void increment_execution_id()=0
virtual void consume_gas(const Gas &dynamic_gas_factor={ 0, 0 })=0
virtual Gas compute_gas_limit_for_call(const Gas &allocated_gas)=0
virtual void get_contract_instance(MemoryInterface &memory, const AztecAddress &contract_address, MemoryAddress dst_offset, uint8_t member_enum)=0
virtual bool gt(const FF &a, const FF &b)=0
virtual void revert_checkpoint()=0
virtual bool note_hash_exists(uint64_t leaf_index, const FF &unique_note_hash) const =0
virtual FF storage_read(const AztecAddress &contract_address, const FF &slot) const =0
virtual uint32_t get_checkpoint_id() const =0
virtual void commit_checkpoint()=0
virtual bool was_storage_written(const AztecAddress &contract_address, const FF &slot) const =0
virtual void note_hash_write(const AztecAddress &contract_address, const FF ¬e_hash)=0
virtual bool nullifier_exists(const AztecAddress &contract_address, const FF &nullifier) const =0
virtual void storage_write(const AztecAddress &contract_address, const FF &slot, const FF &value, bool is_protocol_write)=0
virtual bool l1_to_l2_msg_exists(uint64_t leaf_index, const FF &msg_hash) const =0
virtual void nullifier_write(const AztecAddress &contract_address, const FF &nullifier)=0
virtual TreeStates get_tree_state() const =0
virtual const ExecInstructionSpec & get(ExecutionOpCode opcode) const =0
virtual InternalCallId get_call_id() const =0
virtual InternalCallId get_return_call_id() const =0
virtual InternalCallId get_next_call_id() const =0
virtual const TrackedSideEffects & get_side_effects() const =0
A 1-bit unsigned integer type.
constexpr uint8_t value() const noexcept
std::string format(Args... args)
AztecAddress contract_address
InternalCallStackProvider make_internal_call_stack_provider(const InternalCallStackManagerInterface &internal_call_stack_manager)
CalldataProvider make_calldata_provider(const ContextInterface &context)
ReturnDataProvider make_return_data_provider(const ContextInterface &context, uint32_t rd_mem_offset_in_child, uint32_t rd_size)
size_t get_p_limbs_per_radix_size(size_t radix)
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
uint8_t get_tag_bytes(ValueTag tag)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
RegisterInfo register_info
TreeState public_data_tree
std::optional< std::string > halting_message
SideEffectTracker side_effect_tracker