certora-cli 7.6.3__tar.gz → 7.10.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {certora-cli-7.6.3/certora_cli.egg-info → certora_cli-7.10.1}/PKG-INFO +2 -2
- certora_cli-7.10.1/README.md +1 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSol.py +1 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraBuild.py +108 -8
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraBuildCacheManager.py +22 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraCloudIO.py +31 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraCollectRunMetadata.py +25 -16
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraConfigIO.py +0 -12
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraContext.py +8 -8
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraContextAttribute.py +35 -15
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraContextValidator.py +23 -12
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/equivCheck.py +1 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Mutate/mutateApp.py +148 -69
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Mutate/mutateAttribute.py +1 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Mutate/mutateConstants.py +4 -3
- certora_cli-7.10.1/certora_cli/Mutate/mutateUtil.py +47 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Mutate/mutateValidate.py +19 -4
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/certoraUtils.py +47 -13
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/certoraValidateFuncs.py +16 -2
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/certoraMutate.py +6 -2
- certora_cli-7.10.1/certora_cli/certoraRun.py +254 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1/certora_cli.egg-info}/PKG-INFO +2 -2
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli.egg-info/SOURCES.txt +1 -0
- certora_cli-7.10.1/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_jars/Typechecker.jar +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/setup.py +2 -2
- certora-cli-7.6.3/README.md +0 -1
- certora-cli-7.6.3/certora_cli/certoraRun.py +0 -293
- certora-cli-7.6.3/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
- {certora-cli-7.6.3 → certora_cli-7.10.1}/LICENSE +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/MANIFEST.in +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_bins/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollector.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorFactory.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSolBased.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorVy.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorYul.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraCompilerParameters.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraContextClass.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraContractFuncs.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraExtensionInfo.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraJobList.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraMiniSpecParser.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraNodeFilters.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraType.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraVerifyGenerator.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Mutate/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/ExpectedComparator.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/certoraAttrUtil.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/Shared/certoraLogging.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/certoraEqCheck.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli.egg-info/dependency_links.txt +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli.egg-info/entry_points.txt +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli.egg-info/requires.txt +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli.egg-info/top_level.txt +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/certora_jars/__init__.py +0 -0
- {certora-cli-7.6.3 → certora_cli-7.10.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: certora-cli
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.10.1
|
|
4
4
|
Summary: Runner for the Certora Prover
|
|
5
5
|
Home-page: https://pypi.org/project/certora-cli
|
|
6
6
|
Author: Certora
|
|
@@ -21,4 +21,4 @@ Requires-Dist: tabulate
|
|
|
21
21
|
Requires-Dist: tqdm
|
|
22
22
|
Requires-Dist: StrEnum
|
|
23
23
|
|
|
24
|
-
Commit
|
|
24
|
+
Commit 3dd11d6. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Commit 3dd11d6. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
{certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSol.py
RENAMED
|
@@ -35,7 +35,7 @@ class CompilerLangSol(CompilerLang, metaclass=Singleton):
|
|
|
35
35
|
|
|
36
36
|
@staticmethod
|
|
37
37
|
def compilation_output_path(sdc_name: str) -> Path:
|
|
38
|
-
return get_certora_config_dir() / f"{sdc_name}.standard.json
|
|
38
|
+
return get_certora_config_dir() / f"{sdc_name}.standard.stdout.json"
|
|
39
39
|
|
|
40
40
|
@staticmethod
|
|
41
41
|
def get_supports_imports() -> bool:
|
|
@@ -543,8 +543,79 @@ def generate_full_finder(f: Func, internal_id: int, sym: int,
|
|
|
543
543
|
return used_symbols, finder_gen.renaming() + to_ret
|
|
544
544
|
|
|
545
545
|
|
|
546
|
+
def reprint_ast_type(node: Dict[str, Any]) -> Optional[str]:
|
|
547
|
+
"""
|
|
548
|
+
Tries to pretty print the source code that was passed as node. That is, produce the concrete syntax that
|
|
549
|
+
was parsed by the compiler and then represented by node. This can differ from the "canonical" printing, as it
|
|
550
|
+
may not include the contract qualifier, as this is not always in scope.
|
|
551
|
+
"""
|
|
552
|
+
if "nodeType" not in node:
|
|
553
|
+
return None
|
|
554
|
+
typ = node["nodeType"]
|
|
555
|
+
if typ == "ArrayTypeName":
|
|
556
|
+
if "baseType" not in node:
|
|
557
|
+
return None
|
|
558
|
+
reprint_base = reprint_ast_type(node["baseType"])
|
|
559
|
+
if reprint_base is None:
|
|
560
|
+
return None
|
|
561
|
+
if "length" in node:
|
|
562
|
+
lnode = node["length"]
|
|
563
|
+
if type(lnode) is not dict or "nodeType" not in lnode or lnode["nodeType"] != "Literal" or \
|
|
564
|
+
"value" not in lnode:
|
|
565
|
+
return None
|
|
566
|
+
len_str = lnode["value"]
|
|
567
|
+
else:
|
|
568
|
+
len_str = ""
|
|
569
|
+
return f"{reprint_base}[{len_str}]"
|
|
570
|
+
elif typ == "UserDefinedTypeName":
|
|
571
|
+
if "pathNode" not in node:
|
|
572
|
+
return None
|
|
573
|
+
p_node = node["pathNode"]
|
|
574
|
+
if type(p_node) is not dict or "nodeType" not in p_node or \
|
|
575
|
+
p_node["nodeType"] != "IdentifierPath" or "name" not in p_node:
|
|
576
|
+
return None
|
|
577
|
+
return p_node["name"]
|
|
578
|
+
else:
|
|
579
|
+
return None
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
def get_modifier_param_type_name(ind: int, def_node: Dict[str, Any], f: Func) -> str:
|
|
583
|
+
"""
|
|
584
|
+
Get the type name to use in the modifier for paramter ind. Attempts to reprint the
|
|
585
|
+
literal source code used in the original contract (via reprint_ast_type) or falls back
|
|
586
|
+
to the canonical type name (which may not be valid syntax, see https://certora.atlassian.net/browse/CERT-6284
|
|
587
|
+
"""
|
|
588
|
+
fallback = f.fullArgs[ind].get_source_and_location_str()
|
|
589
|
+
d = def_node.get("parameters", None)
|
|
590
|
+
if type(d) is not dict or d["nodeType"] != "ParameterList" or "parameters" not in d:
|
|
591
|
+
return fallback
|
|
592
|
+
params = d["parameters"]
|
|
593
|
+
if type(params) is not list or len(params) != len(f.fullArgs):
|
|
594
|
+
return fallback
|
|
595
|
+
param_def_node = params[ind]
|
|
596
|
+
if type(param_def_node) is not dict or param_def_node["nodeType"] != "VariableDeclaration" or \
|
|
597
|
+
"typeName" not in param_def_node:
|
|
598
|
+
return fallback
|
|
599
|
+
param_type_node = param_def_node["typeName"]
|
|
600
|
+
if type(param_type_node) is not dict:
|
|
601
|
+
return fallback
|
|
602
|
+
reprint = reprint_ast_type(param_type_node)
|
|
603
|
+
if reprint is None:
|
|
604
|
+
return fallback
|
|
605
|
+
loc_string = ""
|
|
606
|
+
if "storageLocation" in param_def_node:
|
|
607
|
+
if param_def_node["storageLocation"] == "memory":
|
|
608
|
+
loc_string = " memory"
|
|
609
|
+
elif param_def_node["storageLocation"] == "calldata":
|
|
610
|
+
loc_string = " calldata"
|
|
611
|
+
elif param_def_node["storageLocation"] == "storage":
|
|
612
|
+
loc_string = " storage"
|
|
613
|
+
return f"{reprint}{loc_string}"
|
|
614
|
+
|
|
615
|
+
|
|
546
616
|
def generate_modifier_finder(f: Func, internal_id: int, sym: int,
|
|
547
|
-
compiler_collector: CompilerCollectorSol,
|
|
617
|
+
compiler_collector: CompilerCollectorSol, def_node: Dict[str, Any],
|
|
618
|
+
compress: bool) -> Optional[Tuple[str, str]]:
|
|
548
619
|
compressed = generate_finder_body(f, internal_id, sym, compiler_collector, compressed=compress)
|
|
549
620
|
if compressed is None:
|
|
550
621
|
return None
|
|
@@ -552,13 +623,13 @@ def generate_modifier_finder(f: Func, internal_id: int, sym: int,
|
|
|
552
623
|
if len(compressed[0]) == 0:
|
|
553
624
|
return f"{modifier_name}()", f"modifier {modifier_name}() {{ {compressed[1]} _; }}"
|
|
554
625
|
else:
|
|
555
|
-
loggable_types = map(lambda e:
|
|
626
|
+
loggable_types = map(lambda e: get_modifier_param_type_name(e, def_node, f), compressed[0])
|
|
556
627
|
loggable_names = map(lambda e: f.paramNames[e], compressed[0])
|
|
557
628
|
formal_strings = []
|
|
558
629
|
arg_strings = []
|
|
559
630
|
for (logged_ty, logged_name) in zip(loggable_types, loggable_names):
|
|
560
631
|
arg_strings.append(logged_name)
|
|
561
|
-
formal_strings.append(f"{logged_ty
|
|
632
|
+
formal_strings.append(f"{logged_ty} {logged_name}")
|
|
562
633
|
modifier_body = f"modifier {modifier_name}"
|
|
563
634
|
modifier_body += f'({",".join(formal_strings)}) {{ '
|
|
564
635
|
modifier_body += compressed[1]
|
|
@@ -1510,6 +1581,8 @@ class CertoraBuildGenerator:
|
|
|
1510
1581
|
self.context.solc_via_ir or self.context.solc_experimental_via_ir):
|
|
1511
1582
|
# The default optimizer steps (taken from libsolidity/interface/OptimiserSettings.h) but with the
|
|
1512
1583
|
# full inliner step removed
|
|
1584
|
+
solc0_8_26 = "dhfoDgvulfnTUtnIfxa[r]EscLMVcul[j]Trpeulxa[r]cLCTUca[r]LSsTFOtfDnca[r]" + \
|
|
1585
|
+
"IulcscCTUtx[scCTUt]TOntnfDIuljmul[jul]VcTOculjmul"
|
|
1513
1586
|
solc0_8_13_to_0_8_25 = "dhfoDgvulfnTUtnIf[xa[r]EscLMcCTUtTOntnfDIulLculVcul[j]T" + \
|
|
1514
1587
|
"peulxa[rul]xa[r]cLgvifCTUca[r]LSsTFOtfDnca[r]Iulc]jmul[jul]VcTOculjmul"
|
|
1515
1588
|
solc0_8_12 = "dhfoDgvulfnTUtnIf[xa[r]EscLMcCTUtTOntnfDIulLculVcul[j]T" + \
|
|
@@ -1552,6 +1625,8 @@ class CertoraBuildGenerator:
|
|
|
1552
1625
|
yul_optimizer_steps = solc0_8_12
|
|
1553
1626
|
elif minor == 8 and 13 <= patch <= 25:
|
|
1554
1627
|
yul_optimizer_steps = solc0_8_13_to_0_8_25
|
|
1628
|
+
elif minor == 8 and patch == 26:
|
|
1629
|
+
yul_optimizer_steps = solc0_8_26
|
|
1555
1630
|
assert yul_optimizer_steps is not None
|
|
1556
1631
|
|
|
1557
1632
|
yul_optimizer_steps = standard_replacement(yul_optimizer_steps)
|
|
@@ -1566,6 +1641,11 @@ class CertoraBuildGenerator:
|
|
|
1566
1641
|
raise Util.CertoraUserInputError(f"Unrecognized version {major}.{minor}.{patch}")
|
|
1567
1642
|
if (minor == 8 and patch >= 5) or (minor > 8):
|
|
1568
1643
|
settings_dict["optimizer"]["details"] = {"inliner": False}
|
|
1644
|
+
if self.context.disable_solc_optimizers is not None:
|
|
1645
|
+
if "details" not in settings_dict["optimizer"]:
|
|
1646
|
+
settings_dict["optimizer"]["details"] = {}
|
|
1647
|
+
for opt_pass in self.context.disable_solc_optimizers:
|
|
1648
|
+
settings_dict["optimizer"]["details"][opt_pass] = False
|
|
1569
1649
|
|
|
1570
1650
|
def _fill_codegen_related_options(self, contract_file_path: str, settings_dict: Dict[str, Any],
|
|
1571
1651
|
compiler_collector: CompilerCollector) -> None:
|
|
@@ -1863,7 +1943,7 @@ class CertoraBuildGenerator:
|
|
|
1863
1943
|
is equivalent to `main_path = self.context.solc_allow_path`, and that's the best we can do in that
|
|
1864
1944
|
case anyway.
|
|
1865
1945
|
"""
|
|
1866
|
-
main_path = compile_wd / self.context.solc_allow_path
|
|
1946
|
+
main_path = (compile_wd / self.context.solc_allow_path).resolve()
|
|
1867
1947
|
else:
|
|
1868
1948
|
main_path = self.context.solc_allow_path
|
|
1869
1949
|
self.context.solc_cmd_allow_paths = [f'"{main_path}"', '.']
|
|
@@ -2484,7 +2564,7 @@ class CertoraBuildGenerator:
|
|
|
2484
2564
|
# least one modifier already present, and then insert before the first modifier's location in the
|
|
2485
2565
|
# source code
|
|
2486
2566
|
mod_inst = generate_modifier_finder(f, internal_id, function_symbol, sdc.compiler_collector,
|
|
2487
|
-
compress=should_compress)
|
|
2567
|
+
def_node, compress=should_compress)
|
|
2488
2568
|
if mod_inst is None:
|
|
2489
2569
|
instrumentation_logger.debug(f"Modifier generation for {f.name} @ {f.where()} failed")
|
|
2490
2570
|
return None
|
|
@@ -2716,7 +2796,16 @@ class CertoraBuildGenerator:
|
|
|
2716
2796
|
sdc_with_verified_contract_name = next(
|
|
2717
2797
|
curr_sdc for index, curr_sdc in enumerate(sdc_pre_finders) if
|
|
2718
2798
|
curr_sdc.primary_contract == verified_contract_name)
|
|
2719
|
-
|
|
2799
|
+
errs = []
|
|
2800
|
+
for method in context.method:
|
|
2801
|
+
try:
|
|
2802
|
+
self.__verify_method(method, sdc_with_verified_contract_name)
|
|
2803
|
+
except Util.CertoraUserInputError as e:
|
|
2804
|
+
errs.append(e)
|
|
2805
|
+
if len(errs) > 0:
|
|
2806
|
+
raise Util.CertoraUserInputError(
|
|
2807
|
+
f"Some methods as specified via the `method` flag could not be found!{Util.NEW_LINE}{Util.NEW_LINE.join(str(e) for e in errs)}"
|
|
2808
|
+
)
|
|
2720
2809
|
|
|
2721
2810
|
# Build sources tree
|
|
2722
2811
|
build_logger.debug("Building source tree")
|
|
@@ -3041,7 +3130,7 @@ class CertoraBuildGenerator:
|
|
|
3041
3130
|
for k, v in autofinder_remappings.items():
|
|
3042
3131
|
self.function_finder_file_remappings[Util.abs_posix_path(k)] = Util.abs_posix_path(v)
|
|
3043
3132
|
new_sdcs = self.collect_for_file(new_file, i, get_compiler_lang(build_arg_contract_file),
|
|
3044
|
-
Util.get_certora_sources_dir(),
|
|
3133
|
+
Util.get_certora_sources_dir() / self.cwd_rel_in_sources,
|
|
3045
3134
|
path_for_compiler_collector_file,
|
|
3046
3135
|
sdc_pre_finder,
|
|
3047
3136
|
fail_on_compilation_error=False,
|
|
@@ -3394,6 +3483,8 @@ class CertoraBuildGenerator:
|
|
|
3394
3483
|
add_to_sources(Path(file))
|
|
3395
3484
|
if context.bytecode_spec:
|
|
3396
3485
|
sources.add(Path(context.bytecode_spec))
|
|
3486
|
+
if context.yul_abi:
|
|
3487
|
+
sources.add(Path(context.yul_abi))
|
|
3397
3488
|
|
|
3398
3489
|
if hasattr(context,
|
|
3399
3490
|
Attr.ContextAttribute.PROVER_RESOURCE_FILES.get_conf_key()) and context.prover_resource_files:
|
|
@@ -3478,7 +3569,8 @@ def build_from_scratch(certora_build_generator: CertoraBuildGenerator,
|
|
|
3478
3569
|
indent=4,
|
|
3479
3570
|
sort_keys=True)
|
|
3480
3571
|
|
|
3481
|
-
return CachedFiles(certora_build_file, all_contract_files, build_output_props_file, may_store_in_build_cache
|
|
3572
|
+
return CachedFiles(certora_build_file, all_contract_files, build_output_props_file, may_store_in_build_cache,
|
|
3573
|
+
path_with_additional_included_files=absolute_sources_dir)
|
|
3482
3574
|
|
|
3483
3575
|
|
|
3484
3576
|
def build_from_cache_or_scratch(context: CertoraContext,
|
|
@@ -3522,6 +3614,14 @@ def build_from_cache_or_scratch(context: CertoraContext,
|
|
|
3522
3614
|
# write build_cache indicator file
|
|
3523
3615
|
with open(Util.get_build_cache_indicator_file(), "w+") as indicator_handle:
|
|
3524
3616
|
json.dump({"build_cache_hit": True}, indicator_handle)
|
|
3617
|
+
# write in sources all the additional paths found
|
|
3618
|
+
for p in cached_files.path_with_additional_included_files.glob("*"):
|
|
3619
|
+
if p.is_dir():
|
|
3620
|
+
Util.safe_copy_folder(p,
|
|
3621
|
+
Util.get_certora_sources_dir() / p.name,
|
|
3622
|
+
shutil.ignore_patterns())
|
|
3623
|
+
else:
|
|
3624
|
+
shutil.copyfile(p, Util.get_certora_sources_dir() / p.name)
|
|
3525
3625
|
cache_hit = True
|
|
3526
3626
|
else:
|
|
3527
3627
|
# rebuild
|
{certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraBuildCacheManager.py
RENAMED
|
@@ -23,6 +23,9 @@ class CachedFiles:
|
|
|
23
23
|
build_output_props_file: Path
|
|
24
24
|
may_store_in_build_cache: bool
|
|
25
25
|
|
|
26
|
+
# to keep .post_autofinders
|
|
27
|
+
path_with_additional_included_files: Path
|
|
28
|
+
|
|
26
29
|
def all_exist(self, main_cache_entry_dir: Path, sub_cache_key: str) -> bool:
|
|
27
30
|
exist = self.certora_build_file.exists() and \
|
|
28
31
|
self.certora_build_file == main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.certora_build_suffix}"
|
|
@@ -36,6 +39,7 @@ class CachedFiles:
|
|
|
36
39
|
certora_build_suffix = "certora_build.json"
|
|
37
40
|
file_list_suffix = "file_list.json"
|
|
38
41
|
build_output_props_suffix = "build_output_props.json"
|
|
42
|
+
additional_included_files = "additional_included_files"
|
|
39
43
|
|
|
40
44
|
|
|
41
45
|
class CertoraBuildCacheManager:
|
|
@@ -105,8 +109,9 @@ class CertoraBuildCacheManager:
|
|
|
105
109
|
f"but {CachedFiles.build_output_props_suffix} file does not exist")
|
|
106
110
|
return None
|
|
107
111
|
|
|
112
|
+
additional_included_files = main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.additional_included_files}"
|
|
108
113
|
return CachedFiles(certora_build_file, all_contract_files, build_output_props_file,
|
|
109
|
-
may_store_in_build_cache=True)
|
|
114
|
+
may_store_in_build_cache=True, path_with_additional_included_files=additional_included_files)
|
|
110
115
|
|
|
111
116
|
@staticmethod
|
|
112
117
|
def save_build_cache(context: CertoraContext, cached_files: CachedFiles) -> None:
|
|
@@ -151,6 +156,22 @@ class CertoraBuildCacheManager:
|
|
|
151
156
|
# save additional props file
|
|
152
157
|
shutil.copyfile(cached_files.build_output_props_file,
|
|
153
158
|
main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.build_output_props_suffix}")
|
|
159
|
+
# save .post_autofinders from additional included files
|
|
160
|
+
trg_path_with_additional_included_files = \
|
|
161
|
+
main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.additional_included_files}"
|
|
162
|
+
post_autofinder_dirs = list(
|
|
163
|
+
cached_files.path_with_additional_included_files.glob(f"{Util.POST_AUTOFINDER_BACKUP_DIR}.*"))
|
|
164
|
+
for post_autofinder_dir in post_autofinder_dirs:
|
|
165
|
+
trg = trg_path_with_additional_included_files / post_autofinder_dir.name
|
|
166
|
+
if post_autofinder_dir != trg:
|
|
167
|
+
if post_autofinder_dir.is_dir():
|
|
168
|
+
Util.safe_copy_folder(post_autofinder_dir, trg, shutil.ignore_patterns())
|
|
169
|
+
else:
|
|
170
|
+
# highly unlikely .post_autofinder.[digit] will be a file and not a directory,
|
|
171
|
+
# but would rather not crash and future-proof instead
|
|
172
|
+
# (more likely, we may include other types of files and not just autofinder directories, in which
|
|
173
|
+
# case we'll change the variable name accordingly)
|
|
174
|
+
shutil.copyfile(post_autofinder_dir, trg)
|
|
154
175
|
|
|
155
176
|
@staticmethod
|
|
156
177
|
def get_main_cache_key(context: CertoraContext) -> str:
|
|
@@ -21,6 +21,7 @@ from Shared import certoraUtils as Util
|
|
|
21
21
|
import EVMVerifier.certoraContextAttribute as Attr
|
|
22
22
|
import EVMVerifier.certoraContext as Ctx
|
|
23
23
|
from Shared import certoraValidateFuncs as Vf
|
|
24
|
+
from Mutate import mutateUtil as MutUtil
|
|
24
25
|
|
|
25
26
|
from typing import Optional, Dict, Any, List, Union, cast
|
|
26
27
|
from tqdm import tqdm
|
|
@@ -560,6 +561,7 @@ class CloudVerification:
|
|
|
560
561
|
auth_data = {
|
|
561
562
|
"process": self.context.process, "runName": self.runName,
|
|
562
563
|
"run_source": self.context.run_source,
|
|
564
|
+
"group_id": self.context.group_id,
|
|
563
565
|
"branch": self.context.prover_version if self.context.prover_version else '',
|
|
564
566
|
'ci': Util.is_ci_or_git_action()
|
|
565
567
|
}
|
|
@@ -595,6 +597,15 @@ class CloudVerification:
|
|
|
595
597
|
elif arg == '-solanaSummaries':
|
|
596
598
|
is_file = True
|
|
597
599
|
auth_data["jarSettings"] = solana_jar_settings
|
|
600
|
+
elif self.context.is_wasm:
|
|
601
|
+
# We need to strip "../" path component from all file paths because
|
|
602
|
+
# unzip will also do that.
|
|
603
|
+
wasm_jar_settings = []
|
|
604
|
+
for file in self.context.files:
|
|
605
|
+
wasm_jar_settings.append(file.split('../')[-1])
|
|
606
|
+
for arg in jar_settings:
|
|
607
|
+
wasm_jar_settings.append(arg)
|
|
608
|
+
auth_data["jarSettings"] = wasm_jar_settings
|
|
598
609
|
else:
|
|
599
610
|
auth_data["jarSettings"] = jar_settings
|
|
600
611
|
|
|
@@ -728,6 +739,12 @@ class CloudVerification:
|
|
|
728
739
|
elif arg == '-solanaSummaries':
|
|
729
740
|
is_file = True
|
|
730
741
|
result = compress_files(self.ZipFilePath, *paths, short_output=Ctx.is_minimal_cli_output(self.context))
|
|
742
|
+
elif self.context.is_wasm:
|
|
743
|
+
# We zip the wat file
|
|
744
|
+
paths = []
|
|
745
|
+
for file in self.context.files:
|
|
746
|
+
paths.append(Path(file))
|
|
747
|
+
result = compress_files(self.ZipFilePath, *paths, short_output=Ctx.is_minimal_cli_output(self.context))
|
|
731
748
|
else:
|
|
732
749
|
# Zip the log file first separately and again with the rest of the files, so it will not be decompressed
|
|
733
750
|
# on each run in order to save space
|
|
@@ -748,7 +765,17 @@ class CloudVerification:
|
|
|
748
765
|
|
|
749
766
|
cloud_logger.debug("Uploading files...")
|
|
750
767
|
if self.upload(self.presigned_url, self.ZipFilePath):
|
|
751
|
-
|
|
768
|
+
try:
|
|
769
|
+
if self.context.mutation_test_id:
|
|
770
|
+
counter = MutUtil.mutant_counter(self.context.mutation_test_id)
|
|
771
|
+
total = MutUtil.TOTAL_MUTANTS
|
|
772
|
+
Util.print_completion_message(f"Mutation {counter}/{total} submitted to server")
|
|
773
|
+
else:
|
|
774
|
+
Util.print_completion_message("Job submitted to server")
|
|
775
|
+
|
|
776
|
+
except Exception:
|
|
777
|
+
Util.print_completion_message("Job submitted to server")
|
|
778
|
+
|
|
752
779
|
print()
|
|
753
780
|
else: # upload error
|
|
754
781
|
return False
|
|
@@ -881,6 +908,9 @@ class CloudVerification:
|
|
|
881
908
|
print("Please note - failure may be related to using the server"
|
|
882
909
|
f" <{self.context.server.lower()}> which is not a standard server")
|
|
883
910
|
return None
|
|
911
|
+
elif status == 401:
|
|
912
|
+
print("Invalid key or key is missing. Please, make sure you entered a valid key.")
|
|
913
|
+
return None
|
|
884
914
|
elif status >= 500:
|
|
885
915
|
cloud_logger.debug(f'{status} received. Retry...')
|
|
886
916
|
if i < self.verification_request_retries:
|
{certora-cli-7.6.3 → certora_cli-7.10.1}/certora_cli/EVMVerifier/certoraCollectRunMetadata.py
RENAMED
|
@@ -45,7 +45,7 @@ class RunMetaData:
|
|
|
45
45
|
"""
|
|
46
46
|
def __init__(self, raw_args: List[str], conf: Dict[str, Any], origin: str, revision: str,
|
|
47
47
|
branch: str, cwd_relative: Path, dirty: bool, main_spec: Optional[str],
|
|
48
|
-
conf_path: Optional[Path]):
|
|
48
|
+
conf_path: Optional[Path], group_id: Optional[str]):
|
|
49
49
|
self.raw_args = raw_args
|
|
50
50
|
self.conf = conf
|
|
51
51
|
self.origin = origin
|
|
@@ -55,22 +55,27 @@ class RunMetaData:
|
|
|
55
55
|
self.dirty = dirty
|
|
56
56
|
self.main_spec = main_spec
|
|
57
57
|
self.conf_path = conf_path
|
|
58
|
+
self.group_id = group_id
|
|
59
|
+
self.python_version = ".".join(str(x) for x in sys.version_info[:3])
|
|
58
60
|
self.certora_ci_client = Utils.get_certora_ci_name()
|
|
59
61
|
self.timestamp = str(datetime.utcnow().timestamp())
|
|
60
|
-
_,
|
|
62
|
+
_, self.CLI_package_name, self.CLI_version = Utils.get_package_and_version()
|
|
61
63
|
|
|
62
64
|
def __repr__(self) -> str:
|
|
63
65
|
return (
|
|
64
|
-
f" raw_args: {self.raw_args}\n"
|
|
65
|
-
f" conf: {self.conf}\n"
|
|
66
|
-
f" origin: {self.origin}\n"
|
|
67
|
-
f" revision: {self.revision}\n"
|
|
68
|
-
f" branch: {self.branch}\n"
|
|
69
|
-
f" cwd_relative: {self.cwd_relative}\n"
|
|
70
|
-
f" dirty: {self.dirty}\n"
|
|
71
|
-
f" CLI_version: {self.CLI_version}\n"
|
|
72
|
-
f"
|
|
73
|
-
f"
|
|
66
|
+
f" raw_args: {self.raw_args}\n"
|
|
67
|
+
f" conf: {self.conf}\n"
|
|
68
|
+
f" origin: {self.origin}\n"
|
|
69
|
+
f" revision: {self.revision}\n"
|
|
70
|
+
f" branch: {self.branch}\n"
|
|
71
|
+
f" cwd_relative: {self.cwd_relative}\n"
|
|
72
|
+
f" dirty: {self.dirty}\n"
|
|
73
|
+
f" CLI_version: {self.CLI_version}\n"
|
|
74
|
+
f" CLI_package_name: {self.CLI_package_name}\n"
|
|
75
|
+
f" main_spec: {self.main_spec}\n"
|
|
76
|
+
f" conf_path: {self.conf_path}\n"
|
|
77
|
+
f" group_id: {self.group_id}\n"
|
|
78
|
+
f" python_version: {self.python_version}\n"
|
|
74
79
|
f" CertoraCI client: {self.certora_ci_client}\n"
|
|
75
80
|
)
|
|
76
81
|
|
|
@@ -137,7 +142,8 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
137
142
|
cwd_relative=wd,
|
|
138
143
|
dirty=True,
|
|
139
144
|
main_spec=None,
|
|
140
|
-
conf_path=None
|
|
145
|
+
conf_path=None,
|
|
146
|
+
group_id=None)
|
|
141
147
|
|
|
142
148
|
# collect information about current git snapshot
|
|
143
149
|
cwd_abs = wd.resolve()
|
|
@@ -164,7 +170,8 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
164
170
|
cwd_relative=cwd_relative,
|
|
165
171
|
dirty=True,
|
|
166
172
|
main_spec=context.main_spec,
|
|
167
|
-
conf_path=conf_path
|
|
173
|
+
conf_path=conf_path,
|
|
174
|
+
group_id=context.group_id)
|
|
168
175
|
|
|
169
176
|
try:
|
|
170
177
|
sha_out = subprocess.run(['git', 'rev-parse', 'HEAD'], cwd=wd,
|
|
@@ -198,7 +205,8 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
198
205
|
cwd_relative=cwd_relative,
|
|
199
206
|
dirty=dirty,
|
|
200
207
|
main_spec=context.main_spec,
|
|
201
|
-
conf_path=conf_path
|
|
208
|
+
conf_path=conf_path,
|
|
209
|
+
group_id=context.group_id)
|
|
202
210
|
|
|
203
211
|
metadata_logger.debug(f' collected data:\n{str(data)}')
|
|
204
212
|
|
|
@@ -215,4 +223,5 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
215
223
|
cwd_relative=cwd_relative,
|
|
216
224
|
dirty=True,
|
|
217
225
|
main_spec=context.main_spec,
|
|
218
|
-
conf_path=conf_path
|
|
226
|
+
conf_path=conf_path,
|
|
227
|
+
group_id=context.group_id)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import json5
|
|
2
2
|
import logging
|
|
3
|
-
import sys
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
from typing import Dict, Any, Optional
|
|
6
5
|
|
|
@@ -43,17 +42,6 @@ def current_conf_to_file(context: CertoraContext) -> Dict[str, Any]:
|
|
|
43
42
|
run_logger.debug(f"Saving last configuration file to {out_file_path}")
|
|
44
43
|
Ctx.write_output_conf_to_path(context_to_save, out_file_path)
|
|
45
44
|
|
|
46
|
-
# for dumping the conf file and exit user can either call with --conf_output_file or by setting the
|
|
47
|
-
# environment variable CERTORA_DUMP_CONFIG. Using CERTORA_DUMP_CONFIG let the user change the conf file path
|
|
48
|
-
# without tempering with .sh files.
|
|
49
|
-
# NOTE: if you want to run multiple CVT instances simultaneously,
|
|
50
|
-
# you should use consider the --conf_output_file flag and not CERTORA_DUMP_CONFIG.
|
|
51
|
-
|
|
52
|
-
conf_key = Attr.ContextAttribute.CONF_OUTPUT_FILE.get_conf_key()
|
|
53
|
-
conf_output_file = getattr(context, conf_key, None) or Util.get_certora_dump_config()
|
|
54
|
-
if conf_output_file:
|
|
55
|
-
Ctx.write_output_conf_to_path(context_to_save, Path(conf_output_file))
|
|
56
|
-
sys.exit(0)
|
|
57
45
|
return context_to_save
|
|
58
46
|
|
|
59
47
|
|
|
@@ -114,7 +114,9 @@ def get_typechecker_arguments(context: CertoraContext, typechecker_args: Optiona
|
|
|
114
114
|
typecheck_cmd = f"{typecheck_cmd} {' '.join(typechecker_args)}"
|
|
115
115
|
|
|
116
116
|
relevant_args = filter(lambda arg: get_attr_value(context, arg),
|
|
117
|
-
[Attr.ContextAttribute.RULE,
|
|
117
|
+
[Attr.ContextAttribute.RULE,
|
|
118
|
+
Attr.ContextAttribute.EXCLUDE_RULE,
|
|
119
|
+
Attr.ContextAttribute.FOUNDRY_TESTS_MODE])
|
|
118
120
|
args_list = create_jar_flag_list(context, list(relevant_args))
|
|
119
121
|
|
|
120
122
|
return f"{typecheck_cmd} {' '.join(args_list)}"
|
|
@@ -127,7 +129,7 @@ def get_local_run_cmd(context: CertoraContext) -> str:
|
|
|
127
129
|
@return: A command for running the prover locally
|
|
128
130
|
"""
|
|
129
131
|
run_args = []
|
|
130
|
-
if context.is_tac or context.is_solana:
|
|
132
|
+
if context.is_tac or context.is_solana or context.is_wasm:
|
|
131
133
|
run_args.append(context.files[0])
|
|
132
134
|
if context.cache is not None:
|
|
133
135
|
run_args.extend(['-cache', context.cache])
|
|
@@ -140,7 +142,7 @@ def get_local_run_cmd(context: CertoraContext) -> str:
|
|
|
140
142
|
jar_path = context.jar
|
|
141
143
|
else:
|
|
142
144
|
certora_root_dir = Util.get_certora_root_directory().as_posix()
|
|
143
|
-
jar_path = f"{certora_root_dir}/
|
|
145
|
+
jar_path = f"{certora_root_dir}/{Util.EMV_JAR}"
|
|
144
146
|
|
|
145
147
|
if context.allow_solidity_calls_in_quantifiers:
|
|
146
148
|
run_args.extend(['-allowSolidityCallsInQuantifiers true'])
|
|
@@ -184,7 +186,7 @@ class ProverParser(AttrUtil.CertoraArgumentParser):
|
|
|
184
186
|
|
|
185
187
|
Attr.ContextAttribute.print_attr_help()
|
|
186
188
|
console.print("\n\nYou can find detailed documentation of the supported flags here: "
|
|
187
|
-
f"
|
|
189
|
+
f"{Util.print_rich_link(CLI_DOCUMENTATION_URL)}\n\n")
|
|
188
190
|
|
|
189
191
|
return ''
|
|
190
192
|
|
|
@@ -263,10 +265,8 @@ def get_args(args_list: Optional[List[str]] = None) -> Tuple[CertoraContext, Dic
|
|
|
263
265
|
setup_cache(context) # Here context.cache, context.user_defined_cache are set
|
|
264
266
|
|
|
265
267
|
# Setup defaults (defaults are not recorded in conf file)
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if context.run_source is None:
|
|
269
|
-
context.run_source = Vf.RunSources.COMMAND.name.upper()
|
|
268
|
+
context.expected_file = context.expected_file or "expected.json"
|
|
269
|
+
context.run_source = context.run_source or Vf.RunSources.COMMAND.name.upper()
|
|
270
270
|
|
|
271
271
|
context_logger.debug("parsed args successfully.")
|
|
272
272
|
context_logger.debug(f"args= {context}")
|
|
@@ -254,7 +254,8 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
254
254
|
|
|
255
255
|
MULTI_EXAMPLE = CertoraArgument(
|
|
256
256
|
attr_validation_func=Vf.validate_multi_example_value,
|
|
257
|
-
help_msg="Show several examples for failed
|
|
257
|
+
help_msg="Show several counter examples for failed `assert` statements "
|
|
258
|
+
"and several witnesses for verified `satisfy` statements",
|
|
258
259
|
jar_flag='-multipleCEX',
|
|
259
260
|
default_desc="Shows a single example",
|
|
260
261
|
argparse_args={
|
|
@@ -269,8 +270,8 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
269
270
|
|
|
270
271
|
FUNCTION_FINDER_MODE = CertoraArgument(
|
|
271
272
|
attr_validation_func=Vf.validate_function_finder_mode,
|
|
272
|
-
help_msg="Use
|
|
273
|
-
"but may cause
|
|
273
|
+
help_msg="Use `relaxed` mode to increase internal function finders precision, "
|
|
274
|
+
"but may cause `stack too deep` errors unless using `via-ir`",
|
|
274
275
|
default_desc="Takes less stack space but internal functions may be missed",
|
|
275
276
|
argparse_args={
|
|
276
277
|
'nargs': AttrUtil.SINGLE_OR_NONE_OCCURRENCES,
|
|
@@ -588,6 +589,16 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
588
589
|
disables_build_cache=False
|
|
589
590
|
)
|
|
590
591
|
|
|
592
|
+
DISABLE_SOLC_OPTIMIZERS = CertoraArgument(
|
|
593
|
+
arg_type=AttrUtil.AttrArgType.LIST,
|
|
594
|
+
argparse_args={
|
|
595
|
+
'nargs': AttrUtil.ONE_OR_MORE_OCCURRENCES,
|
|
596
|
+
'action': AttrUtil.APPEND
|
|
597
|
+
},
|
|
598
|
+
affects_build_cache_key=True,
|
|
599
|
+
disables_build_cache=False
|
|
600
|
+
)
|
|
601
|
+
|
|
591
602
|
YUL_ABI = CertoraArgument(
|
|
592
603
|
attr_validation_func=Vf.validate_json_file,
|
|
593
604
|
help_msg="An auxiliary ABI file for yul contracts",
|
|
@@ -715,10 +726,12 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
715
726
|
|
|
716
727
|
METHOD = CertoraArgument(
|
|
717
728
|
jar_flag='-method',
|
|
729
|
+
arg_type=AttrUtil.AttrArgType.LIST,
|
|
718
730
|
help_msg="Filter methods to be verified by their signature",
|
|
719
731
|
default_desc="Verifies all public or external methods. In invariants pure and view functions are ignored",
|
|
720
732
|
argparse_args={
|
|
721
|
-
'
|
|
733
|
+
'nargs': AttrUtil.ONE_OR_MORE_OCCURRENCES,
|
|
734
|
+
'action': AttrUtil.APPEND
|
|
722
735
|
},
|
|
723
736
|
affects_build_cache_key=False,
|
|
724
737
|
disables_build_cache=False
|
|
@@ -866,7 +879,7 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
866
879
|
NONDET_MINIMAL_DIFFICULTY = CertoraArgument(
|
|
867
880
|
attr_validation_func=Vf.validate_non_negative_integer,
|
|
868
881
|
jar_flag='-autoNondetMinimalDifficulty',
|
|
869
|
-
help_msg="Set the minimal
|
|
882
|
+
help_msg="Set the minimal `difficulty` threshold for summarization by `nondet_difficult_funcs`",
|
|
870
883
|
default_desc="50",
|
|
871
884
|
argparse_args={
|
|
872
885
|
'action': AttrUtil.UniqueStore
|
|
@@ -1172,15 +1185,6 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
1172
1185
|
disables_build_cache=False
|
|
1173
1186
|
)
|
|
1174
1187
|
|
|
1175
|
-
CONF_OUTPUT_FILE = CertoraArgument(
|
|
1176
|
-
flag='--conf_output_file',
|
|
1177
|
-
argparse_args={
|
|
1178
|
-
'action': AttrUtil.UniqueStore
|
|
1179
|
-
},
|
|
1180
|
-
affects_build_cache_key=False,
|
|
1181
|
-
disables_build_cache=False
|
|
1182
|
-
)
|
|
1183
|
-
|
|
1184
1188
|
RUN_SOURCE = CertoraArgument(
|
|
1185
1189
|
attr_validation_func=Vf.validate_run_source,
|
|
1186
1190
|
argparse_args={
|
|
@@ -1404,6 +1408,22 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
1404
1408
|
disables_build_cache=True
|
|
1405
1409
|
)
|
|
1406
1410
|
|
|
1411
|
+
GROUP_ID = CertoraArgument(
|
|
1412
|
+
attr_validation_func=Vf.validate_uuid,
|
|
1413
|
+
affects_build_cache_key=False,
|
|
1414
|
+
disables_build_cache=False
|
|
1415
|
+
)
|
|
1416
|
+
|
|
1417
|
+
FOUNDRY_TESTS_MODE = CertoraArgument(
|
|
1418
|
+
arg_type=AttrUtil.AttrArgType.BOOLEAN,
|
|
1419
|
+
jar_flag='-foundry',
|
|
1420
|
+
argparse_args={
|
|
1421
|
+
'action': AttrUtil.STORE_TRUE
|
|
1422
|
+
},
|
|
1423
|
+
affects_build_cache_key=False,
|
|
1424
|
+
disables_build_cache=False
|
|
1425
|
+
)
|
|
1426
|
+
|
|
1407
1427
|
def validate_value(self, value: str, cli_flag: bool = True) -> None:
|
|
1408
1428
|
if self.value.attr_validation_func is not None:
|
|
1409
1429
|
try:
|
|
@@ -1426,4 +1446,4 @@ class ContextAttribute(AttrUtil.BaseAttribute):
|
|
|
1426
1446
|
|
|
1427
1447
|
@lru_cache(maxsize=1, typed=False)
|
|
1428
1448
|
def all_context_keys() -> List[str]:
|
|
1429
|
-
return [attr.get_conf_key() for attr in ContextAttribute
|
|
1449
|
+
return [attr.get_conf_key() for attr in ContextAttribute]
|