Skip to content

Commit

Permalink
Enable breaking on all foundry actions (#261)
Browse files Browse the repository at this point in the history
* kontrol/prove: make sure to break on foundry calls/returns to not generate those rules for KEVM

* kontrol/cheatcodes.md, kontrol/prove.py: break on more cheatcode rules to get maximal basic-blocks for KEVM claims

* kontrol/{prove,options,__main__}: add option --break-on-foundry for breaking on all foundry rules

* kontrol/{options,prove}: allow KEVMs --break-on-storage cut-rule too

* Set Version: 0.1.105

* kontrol/{options,__main__,prove}: enable --break-on-basic-blocks

* Set Version: 0.1.106

* kontrol/: rename --break-on-foundry => --break-on-cheatcodes

* kontrol/prove: enumerate rules directly from definition instead of manually

* Set Version: 0.1.107

* Set Version: 0.1.108

---------

Co-authored-by: devops <[email protected]>
Co-authored-by: Andrei Văcaru <[email protected]>
  • Loading branch information
3 people authored Jan 11, 2024
1 parent a27a5e0 commit d5d097f
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.107
0.1.108
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "kontrol"
version = "0.1.107"
version = "0.1.108"
description = "Foundry integration for KEVM"
authors = [
"Runtime Verification, Inc. <[email protected]>",
Expand Down
2 changes: 1 addition & 1 deletion src/kontrol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
if TYPE_CHECKING:
from typing import Final

VERSION: Final = '0.1.107'
VERSION: Final = '0.1.108'
9 changes: 9 additions & 0 deletions src/kontrol/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ def exec_prove(
break_on_calls: bool = True,
break_on_storage: bool = False,
break_on_basic_blocks: bool = False,
break_on_cheatcodes: bool = False,
bmc_depth: int | None = None,
bug_report: BugReport | None = None,
kore_rpc_command: str | Iterable[str] | None = None,
Expand Down Expand Up @@ -258,6 +259,7 @@ def exec_prove(
break_on_calls=break_on_calls,
break_on_storage=break_on_storage,
break_on_basic_blocks=break_on_basic_blocks,
break_on_cheatcodes=break_on_cheatcodes,
workers=workers,
counterexample_info=counterexample_info,
max_iterations=max_iterations,
Expand Down Expand Up @@ -733,6 +735,13 @@ def _parse_test_version_tuple(value: str) -> tuple[str, int | None]:
prove_args.add_argument(
'--use-gas', dest='use_gas', default=False, action='store_true', help='Enables gas computation in KEVM.'
)
prove_args.add_argument(
'--break-on-cheatcodes',
dest='break_on_cheatcodes',
default=False,
action='store_true',
help='Break on all Foundry rules.',
)

show_args = command_parser.add_parser(
'show',
Expand Down
9 changes: 6 additions & 3 deletions src/kontrol/kdist/cheatcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,8 @@ The check will be inserted only if the current depth is the same as the depth at
WThe `#checkRevert` will be used to compare the status code of the execution and the output of the call against the expect reason provided.

```k
rule <k> #next [ _OP:CallOp ] ~> (. => #checkRevert ~> #updateRevertOutput RETSTART RETWIDTH) ~> #execute ... </k>
rule [foundry.set.expectrevert.1]:
<k> #next [ _OP:CallOp ] ~> (. => #checkRevert ~> #updateRevertOutput RETSTART RETWIDTH) ~> #execute ... </k>
<callDepth> CD </callDepth>
<wordStack> _ : _ : _ : _ : _ : RETSTART : RETWIDTH : _WS </wordStack>
<expectedRevert>
Expand All @@ -466,7 +467,8 @@ WThe `#checkRevert` will be used to compare the status code of the execution and
</expectedRevert>
[priority(40)]
rule <k> #next [ _OP:CallSixOp ] ~> (. => #checkRevert ~> #updateRevertOutput RETSTART RETWIDTH) ~> #execute ... </k>
rule [foundry.set.expectrevert.2]:
<k> #next [ _OP:CallSixOp ] ~> (. => #checkRevert ~> #updateRevertOutput RETSTART RETWIDTH) ~> #execute ... </k>
<callDepth> CD </callDepth>
<wordStack> _ : _ : _ : _ : RETSTART : RETWIDTH : _WS </wordStack>
<expectedRevert>
Expand All @@ -476,7 +478,8 @@ WThe `#checkRevert` will be used to compare the status code of the execution and
</expectedRevert>
[priority(40)]
rule <k> #next [ OP:OpCode ] ~> (. => #checkRevert) ~> #execute ... </k>
rule [foundry.set.expectrevert.3]:
<k> #next [ OP:OpCode ] ~> (. => #checkRevert) ~> #execute ... </k>
<callDepth> CD </callDepth>
<expectedRevert>
<isRevertExpected> true </isRevertExpected>
Expand Down
3 changes: 3 additions & 0 deletions src/kontrol/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class ProveOptions:
break_on_calls: bool
break_on_storage: bool
break_on_basic_blocks: bool
break_on_cheatcodes: bool
workers: int
counterexample_info: bool
max_iterations: int | None
Expand All @@ -40,6 +41,7 @@ def __init__(
break_on_calls: bool = True,
break_on_storage: bool = False,
break_on_basic_blocks: bool = False,
break_on_cheatcodes: bool = False,
workers: int = 1,
counterexample_info: bool = False,
max_iterations: int | None = None,
Expand All @@ -57,6 +59,7 @@ def __init__(
object.__setattr__(self, 'break_on_calls', break_on_calls)
object.__setattr__(self, 'break_on_storage', break_on_storage)
object.__setattr__(self, 'break_on_basic_blocks', break_on_basic_blocks)
object.__setattr__(self, 'break_on_cheatcodes', break_on_cheatcodes)
object.__setattr__(self, 'workers', workers)
object.__setattr__(self, 'counterexample_info', counterexample_info)
object.__setattr__(self, 'max_iterations', max_iterations)
Expand Down
18 changes: 12 additions & 6 deletions src/kontrol/prove.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,24 @@ def init_and_run_proof(test: FoundryTest) -> Proof:
use_gas=prove_options.use_gas,
)

cut_point_rules = KEVMSemantics.cut_point_rules(
prove_options.break_on_jumpi,
prove_options.break_on_calls,
prove_options.break_on_storage,
prove_options.break_on_basic_blocks,
)
if prove_options.break_on_cheatcodes:
cut_point_rules.extend(
rule.label for rule in foundry.kevm.definition.all_modules_dict['FOUNDRY-CHEAT-CODES'].rules
)

run_prover(
foundry.kevm,
proof,
kcfg_explore,
max_depth=prove_options.max_depth,
max_iterations=prove_options.max_iterations,
cut_point_rules=KEVMSemantics.cut_point_rules(
prove_options.break_on_jumpi,
prove_options.break_on_calls,
prove_options.break_on_storage,
prove_options.break_on_basic_blocks,
),
cut_point_rules=cut_point_rules,
terminal_rules=KEVMSemantics.terminal_rules(prove_options.break_every_step),
counterexample_info=prove_options.counterexample_info,
)
Expand Down

0 comments on commit d5d097f

Please sign in to comment.