evm 1.1.1

Ethereum Virtual Machine
Documentation
use alloc::vec::Vec;
use evm_interpreter::{Capture, ExitError, ExitResult, Interpreter};

/// Control for an invoker.
pub enum InvokerControl<I, S> {
	/// Pushing the call stack.
	Enter(I),
	/// Directly exit, not pushing the call stack.
	DirectExit(InvokerExit<S>),
}

/// The exit value of an invoker call, containing the result, substate, and return data.
pub struct InvokerExit<S> {
	/// The exit result.
	pub result: ExitResult,
	/// The substate, if available.
	pub substate: Option<S>,
	/// The return data.
	pub retval: Vec<u8>,
}

/// An invoker, responsible for pushing/poping values in the call stack.
pub trait Invoker<H> {
	/// State type.
	type State;
	/// Interpreter type.
	type Interpreter: Interpreter<H, State = Self::State>;
	/// Possible interrupt type that may be returned by the call stack.
	type Interrupt;

	/// Type for transaction arguments.
	type TransactArgs;
	/// The invoke of a top-layer transaction call stack. When finalizing a
	/// transaction, this invoke is used to figure out the finalization routine.
	type TransactInvoke;
	/// The returned value of the transaction.
	type TransactValue;
	/// The invoke of a sub-layer call stack. When exiting a call stack, this
	/// invoke is used to figure out the exit routine.
	type SubstackInvoke;

	/// Create a new transaction with the given transaction arguments.
	#[allow(clippy::type_complexity)]
	fn new_transact(
		&self,
		args: Self::TransactArgs,
		handler: &mut H,
	) -> Result<
		(
			Self::TransactInvoke,
			InvokerControl<Self::Interpreter, Self::State>,
		),
		ExitError,
	>;

	/// Finalize a transaction.
	fn finalize_transact(
		&self,
		invoke: &Self::TransactInvoke,
		exit: InvokerExit<Self::State>,
		handler: &mut H,
	) -> Result<Self::TransactValue, ExitError>;

	/// Enter a sub-layer call stack.
	#[allow(clippy::type_complexity)]
	fn enter_substack(
		&self,
		trap: <Self::Interpreter as Interpreter<H>>::Trap,
		machine: &mut Self::Interpreter,
		handler: &mut H,
		depth: usize,
	) -> Capture<
		Result<
			(
				Self::SubstackInvoke,
				InvokerControl<Self::Interpreter, Self::State>,
			),
			ExitError,
		>,
		Self::Interrupt,
	>;

	/// Exit a sub-layer call stack.
	fn exit_substack(
		&self,
		trap_data: Self::SubstackInvoke,
		exit: InvokerExit<Self::State>,
		parent: &mut Self::Interpreter,
		handler: &mut H,
	) -> Result<(), ExitError>;
}