evm v0.1.14 EVM.Functions

Set of functions defined in the Yellow Paper that do not logically fit in other modules.

Link to this section Summary

Functions

Returns whether or not the current program is in an exceptional halting state. This may be due to running out of gas, having an invalid instruction, having a stack underflow, having an invalid jump destination or having a stack overflow

Returns whether or not the current program is halting due to a return or terminal statement

Link to this section Functions

Link to this function is_exception_halt?(machine_state, exec_env)
is_exception_halt?(EVM.MachineState.t, EVM.ExecEnv.t) ::
  :continue |
  {:halt, String.t}

Returns whether or not the current program is in an exceptional halting state. This may be due to running out of gas, having an invalid instruction, having a stack underflow, having an invalid jump destination or having a stack overflow.

This is defined as Z in Eq.(126) of the Yellow Paper.

Examples

# TODO: Once we add gas cost, make this more reasonable
# TODO: How do we pass in state?
iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff}, %EVM.ExecEnv{machine_code: <<0xfe>>})
{:halt, :undefined_instruction}

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: []}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:add)>>})
{:halt, :stack_underflow}

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: [5]}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:jump)>>})
{:halt, :invalid_jump_destination}

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: [1]}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:jump), EVM.Operation.encode(:jumpdest)>>})
:continue

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: [1, 5]}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:jumpi)>>})
{:halt, :invalid_jump_destination}

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: [1, 5]}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:jumpi), EVM.Operation.encode(:jumpdest)>>})
:continue

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: (for _ <- 1..1024, do: 0x0)}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:stop)>>})
:continue

iex> EVM.Functions.is_exception_halt?(%EVM.MachineState{program_counter: 0, gas: 0xffff, stack: (for _ <- 1..1024, do: 0x0)}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:push1)>>})
{:halt, :stack_overflow}
Link to this function is_normal_halting?(machine_state, exec_env)
is_normal_halting?(EVM.MachineState.t, EVM.ExecEnv.t) ::
  nil |
  binary

Returns whether or not the current program is halting due to a return or terminal statement.

Examples

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{program_counter: 0}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:add)>>})
nil

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{program_counter: 0}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:mul)>>})
nil

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{program_counter: 0}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:stop)>>})
<<>>

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{program_counter: 0}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:suicide)>>})
<<>>

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{stack: [0, 1], memory: <<0xabcd::16>>}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:return)>>})
<<0xab>>

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{stack: [0, 2], memory: <<0xabcd::16>>}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:return)>>})
<<0xab, 0xcd>>

iex> EVM.Functions.is_normal_halting?(%EVM.MachineState{stack: [1, 1], memory: <<0xabcd::16>>}, %EVM.ExecEnv{machine_code: <<EVM.Operation.encode(:return)>>})
<<0xcd>>
Link to this function max_stack_depth()