Skip to content

Commit

Permalink
More docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
disconnect3d committed Jan 7, 2019
1 parent 03bd5ac commit 8eb15a0
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 25 deletions.
21 changes: 10 additions & 11 deletions manticore/core/executor.py
Expand Up @@ -57,7 +57,7 @@ def locked_context(self, key=None, default=dict):
with self._executor.locked_context('.'.join(keys), default) as policy_context:
yield policy_context

def _add_state_callback(self, state_id, state):
def _add_state_callback(self, state, state_id):
''' Save summarize(state) on policy shared context before
the state is stored
'''
Expand Down Expand Up @@ -244,23 +244,22 @@ def locked_context(self, key=None, default=dict):
self._shared_context[key] = sub_context

def _register_state_callbacks(self, state, state_id):
'''
Install forwarding callbacks in state so the events can go up.
Going up, we prepend state in the arguments.
'''
"""
Install forwarding callbacks in state so the events can go up.
Going up, we prepend state in the arguments.
"""
# Forward all state signals
self.forward_events_from(state, True)

def enqueue(self, state):
'''
Enqueue state.
Save state on storage, assigns an id to it, then add it to the
priority queue
'''
"""
Enqueue state.
Save state on storage, assigns an id to it, then add it to the priority queue.
"""
# save the state to secondary storage
state_id = self._workspace.save_state(state)
self.put(state_id)
self._publish('did_enqueue_state', state_id, state)
self._publish('did_enqueue_state', state, state_id)
return state_id

def load_workspace(self):
Expand Down
121 changes: 107 additions & 14 deletions manticore/ethereum/plugins.py
@@ -1,5 +1,3 @@
import sys

import logging
from functools import reduce

Expand Down Expand Up @@ -35,6 +33,8 @@ def will_start_run_callback(self, state):
A = manticore.solidity_create_contract(..., contract_name='A')
B = manticore.solidity_create_contract(..., contract_name='B')
A.a(B)
:type state: manticore.ethereum.State
"""
pass

Expand All @@ -52,38 +52,131 @@ def will_open_transaction_callback(self, state, tx):
contract A { function a(B b) { b.b(); } }
contract B { function b() {} }
The A.a(B) call will open two transactions.
B.b() opens one transaction while A.a(B) opens two transactions.
The `tx.is_human` can be used to determine if the transaction has been explicitly called by the user
(from a manticore script) or if it is an internal transaction (e.g. b.b() called from A.a(B)).
`tx.is_human` can be used to determine whether it is human or internal transaction.
:type state: manticore.ethereum.State
:type tx: manticore.ethereum.evm.Transaction
"""
pass

def will_close_transaction_callback(self, state, tx):
logger.info('will close a transaction %r %r', state, tx)
"""
Called when a transaction is closed. See also `will_open_transaction_callback`.
:type state: manticore.ethereum.State
:type tx: manticore.ethereum.evm.Transaction
"""
pass

def will_execute_instruction_callback(self, state, instruction, arguments):
logger.info('will_execute_instruction %r %r %r', state, instruction, arguments)
"""
Called before an instruction is executed.
The arguments may be symbolic.
:type state: manticore.ethereum.State
:type instruction: pyevmasm.Instruction
:type arguments: list
"""
pass

def did_execute_instruction_callback(self, state, last_instruction, last_arguments, result):
logger.info('did_execute_instruction %r %r %r %r', state, last_instruction, last_arguments, result)
"""
Called after an instruction was executed.
The last_arguments and result may be symbolic.
:type state: manticore.ethereum.State
:type last_instruction: pyevmasm.Instruction
:type last_arguments: list
:type result: typing.Union[int, manticore.core.smtlib.expression.Expression]
"""
pass

def will_fork_state_callback(self, parent_state, expression, solutions, policy):
logger.info('will_fork_state %r %r %r %r', parent_state, expression, solutions, policy)
"""
:param expression: expression that we fork on
:param solutions: tuple of solutions (values) that the state will fork to
:param policy: fork policy string
:type parent_state: manticore.ethereum.State
:type expression: manticore.core.smtlib.expression.Expression
:type solutions: Any
:type policy: str
"""
pass

def did_fork_state_callback(self, child_state, expression, new_value, policy):
logger.info('did_fork_state %r %r %r %r', child_state, expression, new_value, policy)
"""
def did_load_state_callback(self, state, state_id):
logger.info('did_load_state %r %r', state, state_id)
:type child_state: manticore.ethereum.State
:type expression: manticore.core.smtlib.expression.
:type new_value: TODO / FIXME
:type policy: str
"""
pass

def did_enqueue_state_callback(self, state, state_id):
logger.info('did_enqueue_state %r %r', state, state_id)
"""
Called after the state has been enqueued (saved into workspace).
:type state: manticore.ethereum.State
:type state_id: int
"""
pass

def will_load_state_callback(self, state_id):
"""
Called before loading a state with given id.
:type state_id: int
"""
pass

def did_load_state_callback(self, state, state_id):
"""
Called after the state has been loaded.
:type state: manticore.ethereum.State
:type state_id: int
"""
pass

def will_terminate_state_callback(self, state, state_id, exception):
logger.info('will_terminate_state %r %r %r', state, state_id, exception)
"""
Called when a state is terminated. This happens e.g. when:
* state ended with RETURN instruction
* during a shutdown (given timeout passed or user cancelled manticore)
* we entered a state we cannot solve (e.g. no matching keccak256)
* state tries to execute an unimplemented instruction
:type state: manticore.ethereum.State
:type state_id: int
:type exception: manticore.core.state.TerminateState
"""
pass

def will_generate_testcase_callback(self, state, testcase, message):
logger.info('will_generate_testcase %r %r %r', state, testcase, message)
"""
Data shared between states should be saved in `self.context` dict.
Data related to given state should be saved in `state.context` dict.
:param testcase: let us save additional information about given state to the workspace e.g.:
with testcase.open_stream('something') as f:
f.write('some information')
Will save a file called `state_XXXXXX.something` in the workspace.
:param message: Message that was sent when generating testcase; usually a result of transaction (e.g. STOP)
or user defined message.
:type state: manticore.ethereum.State
:type testcase: manticore.core.workspace.Testcase
:type message: str
"""
pass


class FilterFunctions(Plugin):
Expand Down
5 changes: 5 additions & 0 deletions manticore/platforms/evm.py
Expand Up @@ -238,6 +238,11 @@ def __reduce__(self):
def __str__(self):
return 'Transaction({:s}, from=0x{:x}, to=0x{:x}, value={!r}, depth={:d}, data={!r}, result={!r}..)'.format(self.sort, self.caller, self.address, self.value, self.depth, self.data, self.result)

def __repr__(self):
if self.sort == 'CALL':
return f'Tx CALL(func_sig={self.data[:4]}) -> {self.result}'
else:
return f'Tx {self.sort} -> {self.result}'

# Exceptions...
class EVMException(Exception):
Expand Down

0 comments on commit 8eb15a0

Please sign in to comment.