|
|
|
@ -124,8 +124,19 @@ class LaserEVM: |
|
|
|
|
new_global_states = Instruction(op_code, self.dynamic_loader).evaluate(global_state) |
|
|
|
|
|
|
|
|
|
except VmException as e: |
|
|
|
|
logging.debug("Encountered a VmException, ending path: `{}`".format(str(e))) |
|
|
|
|
new_global_states = [] |
|
|
|
|
transaction, return_global_state = global_state.transaction_stack.pop() |
|
|
|
|
|
|
|
|
|
if return_global_state is None: |
|
|
|
|
# In this case we don't put an unmodified world state in the open_states list Since in the case of an |
|
|
|
|
# exceptional halt all changes should be discarded, and this world state would not provide us with a |
|
|
|
|
# previously unseen world state |
|
|
|
|
logging.debug("Encountered a VmException, ending path: `{}`".format(str(e))) |
|
|
|
|
new_global_states = [] |
|
|
|
|
else: |
|
|
|
|
# First execute the post hook for the transaction ending instruction |
|
|
|
|
self._execute_post_hook(op_code, [global_state]) |
|
|
|
|
new_global_states = self._end_message_call(return_global_state, global_state, |
|
|
|
|
revert_changes=True, return_data=None) |
|
|
|
|
|
|
|
|
|
except TransactionStartSignal as e: |
|
|
|
|
# Setup new global state |
|
|
|
@ -149,25 +160,32 @@ class LaserEVM: |
|
|
|
|
# First execute the post hook for the transaction ending instruction |
|
|
|
|
self._execute_post_hook(op_code, [e.global_state]) |
|
|
|
|
|
|
|
|
|
# Resume execution of the transaction initializing instruction |
|
|
|
|
op_code = return_global_state.environment.code.instruction_list[return_global_state.mstate.pc]['opcode'] |
|
|
|
|
new_global_states = self._end_message_call(return_global_state, global_state, |
|
|
|
|
revert_changes=False, return_data=transaction.return_data) |
|
|
|
|
|
|
|
|
|
# Set execution result in the return_state |
|
|
|
|
return_global_state.last_return_data = transaction.return_data |
|
|
|
|
return_global_state.world_state = copy(global_state.world_state) |
|
|
|
|
return_global_state.environment.active_account = \ |
|
|
|
|
global_state.accounts[return_global_state.environment.active_account.address] |
|
|
|
|
self._execute_post_hook(op_code, new_global_states) |
|
|
|
|
|
|
|
|
|
# Execute the post instruction handler |
|
|
|
|
new_global_states = Instruction(op_code, self.dynamic_loader).evaluate(return_global_state, True) |
|
|
|
|
return new_global_states, op_code |
|
|
|
|
|
|
|
|
|
# In order to get a nice call graph we need to set the nodes here |
|
|
|
|
for state in new_global_states: |
|
|
|
|
state.node = global_state.node |
|
|
|
|
def _end_message_call(self, return_global_state, global_state, revert_changes=False, return_data=None): |
|
|
|
|
# Resume execution of the transaction initializing instruction |
|
|
|
|
op_code = return_global_state.environment.code.instruction_list[return_global_state.mstate.pc]['opcode'] |
|
|
|
|
|
|
|
|
|
self._execute_post_hook(op_code, new_global_states) |
|
|
|
|
# Set execution result in the return_state |
|
|
|
|
return_global_state.last_return_data = return_data |
|
|
|
|
if not revert_changes: |
|
|
|
|
return_global_state.world_state = copy(global_state.world_state) |
|
|
|
|
return_global_state.environment.active_account = \ |
|
|
|
|
global_state.accounts[return_global_state.environment.active_account.address] |
|
|
|
|
|
|
|
|
|
return new_global_states, op_code |
|
|
|
|
# Execute the post instruction handler |
|
|
|
|
new_global_states = Instruction(op_code, self.dynamic_loader).evaluate(return_global_state, True) |
|
|
|
|
|
|
|
|
|
# In order to get a nice call graph we need to set the nodes here |
|
|
|
|
for state in new_global_states: |
|
|
|
|
state.node = global_state.node |
|
|
|
|
|
|
|
|
|
return new_global_states |
|
|
|
|
|
|
|
|
|
def _measure_coverage(self, global_state): |
|
|
|
|
code = global_state.environment.code.bytecode |
|
|
|
|