mirror of https://github.com/ConsenSys/mythril
Beam search (#1606)
* Init config dir * Fix solc optimizer * Add beam search * Use dict over referencepull/1608/head
parent
8fbe2e2748
commit
7d3f9b5842
@ -0,0 +1,31 @@ |
|||||||
|
from typing import List |
||||||
|
|
||||||
|
from mythril.laser.ethereum.state.global_state import GlobalState |
||||||
|
from . import BasicSearchStrategy |
||||||
|
|
||||||
|
|
||||||
|
class BeamSearch(BasicSearchStrategy): |
||||||
|
"""chooses a random state from the worklist with equal likelihood.""" |
||||||
|
|
||||||
|
def __init__(self, work_list, max_depth, beam_width, **kwargs): |
||||||
|
super().__init__(work_list, max_depth) |
||||||
|
self.beam_width = beam_width |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def beam_priority(state): |
||||||
|
return sum([annotation.search_importance for annotation in state._annotations]) |
||||||
|
|
||||||
|
def sort_and_eliminate_states(self): |
||||||
|
self.work_list.sort(key=lambda state: self.beam_priority(state), reverse=True) |
||||||
|
del self.work_list[self.beam_width :] |
||||||
|
|
||||||
|
def get_strategic_global_state(self) -> GlobalState: |
||||||
|
""" |
||||||
|
|
||||||
|
:return: |
||||||
|
""" |
||||||
|
self.sort_and_eliminate_states() |
||||||
|
if len(self.work_list) > 0: |
||||||
|
return self.work_list.pop(0) |
||||||
|
else: |
||||||
|
raise IndexError |
@ -0,0 +1,108 @@ |
|||||||
|
import pytest |
||||||
|
from mythril.laser.ethereum.strategy.beam import ( |
||||||
|
BeamSearch, |
||||||
|
) |
||||||
|
from mythril.disassembler.disassembly import Disassembly |
||||||
|
from mythril.laser.ethereum.state.environment import Environment |
||||||
|
from mythril.laser.ethereum.state.machine_state import MachineState |
||||||
|
from mythril.laser.ethereum.state.global_state import GlobalState |
||||||
|
from mythril.laser.ethereum.state.world_state import WorldState |
||||||
|
from mythril.analysis.potential_issues import PotentialIssuesAnnotation |
||||||
|
|
||||||
|
world_state = WorldState() |
||||||
|
account = world_state.create_account(balance=10, address=101) |
||||||
|
account.code = Disassembly("60606040") |
||||||
|
environment = Environment(account, None, None, None, None, None, None) |
||||||
|
potential_issues = PotentialIssuesAnnotation() |
||||||
|
# It is a hassle to construct multiple issues |
||||||
|
potential_issues.potential_issues = [0, 0] |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize( |
||||||
|
"state, priority", |
||||||
|
[ |
||||||
|
( |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[PotentialIssuesAnnotation()], |
||||||
|
), |
||||||
|
0, |
||||||
|
), |
||||||
|
( |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[potential_issues], |
||||||
|
), |
||||||
|
20, |
||||||
|
), |
||||||
|
], |
||||||
|
) |
||||||
|
def test_priority_sum(state, priority): |
||||||
|
assert priority == BeamSearch.beam_priority(state) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize( |
||||||
|
"states, width", |
||||||
|
[ |
||||||
|
( |
||||||
|
[ |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[PotentialIssuesAnnotation()], |
||||||
|
), |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[potential_issues], |
||||||
|
), |
||||||
|
], |
||||||
|
1, |
||||||
|
), |
||||||
|
( |
||||||
|
100 |
||||||
|
* [ |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[PotentialIssuesAnnotation()], |
||||||
|
) |
||||||
|
], |
||||||
|
1, |
||||||
|
), |
||||||
|
( |
||||||
|
100 |
||||||
|
* [ |
||||||
|
GlobalState( |
||||||
|
world_state, |
||||||
|
environment, |
||||||
|
None, |
||||||
|
MachineState(gas_limit=8000000), |
||||||
|
annotations=[PotentialIssuesAnnotation()], |
||||||
|
) |
||||||
|
], |
||||||
|
0, |
||||||
|
), |
||||||
|
], |
||||||
|
) |
||||||
|
def test_elimination(states, width): |
||||||
|
strategy = BeamSearch(states, max_depth=100, beam_width=width) |
||||||
|
strategy.sort_and_eliminate_states() |
||||||
|
|
||||||
|
assert len(strategy.work_list) <= width |
||||||
|
for i in range(len(strategy.work_list) - 1): |
||||||
|
assert strategy.beam_priority(strategy.work_list[i]) >= strategy.beam_priority( |
||||||
|
strategy.work_list[i + 1] |
||||||
|
) |
Loading…
Reference in new issue