certora-cli 7.10.1__tar.gz → 7.14.2__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.10.1/certora_cli.egg-info → certora_cli-7.14.2}/PKG-INFO +2 -2
- certora_cli-7.14.2/README.md +1 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraBuild.py +8 -9
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraCloudIO.py +10 -10
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraCollectRunMetadata.py +11 -8
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraConfigIO.py +24 -20
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraContext.py +107 -51
- certora_cli-7.10.1/certora_cli/EVMVerifier/certoraContextAttribute.py → certora_cli-7.14.2/certora_cli/EVMVerifier/certoraContextAttributes.py +670 -644
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraContextValidator.py +28 -45
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/equivCheck.py +1 -1
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Mutate/mutateApp.py +195 -143
- certora_cli-7.10.1/certora_cli/Mutate/mutateAttribute.py → certora_cli-7.14.2/certora_cli/Mutate/mutateAttributes.py +32 -55
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Mutate/mutateConstants.py +7 -3
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Mutate/mutateValidate.py +18 -17
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/certoraAttrUtil.py +74 -25
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/certoraUtils.py +17 -58
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/certoraValidateFuncs.py +30 -22
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/certoraRun.py +40 -22
- {certora_cli-7.10.1 → certora_cli-7.14.2/certora_cli.egg-info}/PKG-INFO +2 -2
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli.egg-info/SOURCES.txt +2 -2
- certora_cli-7.14.2/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_jars/Typechecker.jar +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/setup.py +2 -2
- certora_cli-7.10.1/README.md +0 -1
- certora_cli-7.10.1/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
- {certora_cli-7.10.1 → certora_cli-7.14.2}/LICENSE +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/MANIFEST.in +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_bins/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollector.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollectorFactory.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSol.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollectorSolBased.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollectorVy.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/CompilerCollectorYul.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/Compiler/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraBuildCacheManager.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraCompilerParameters.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraContextClass.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraContractFuncs.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraExtensionInfo.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraJobList.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraMiniSpecParser.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraNodeFilters.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraType.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraVerifyGenerator.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Mutate/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Mutate/mutateUtil.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/ExpectedComparator.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/Shared/certoraLogging.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/certoraEqCheck.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/certoraMutate.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli.egg-info/dependency_links.txt +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli.egg-info/entry_points.txt +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli.egg-info/requires.txt +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli.egg-info/top_level.txt +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/certora_jars/__init__.py +0 -0
- {certora_cli-7.10.1 → certora_cli-7.14.2}/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.14.2
|
|
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 fe5e093. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Commit fe5e093. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
|
|
@@ -31,11 +31,12 @@ from EVMVerifier.certoraNodeFilters import NodeFilters as Nf
|
|
|
31
31
|
import EVMVerifier.certoraType as CT
|
|
32
32
|
|
|
33
33
|
from EVMVerifier.certoraContextClass import CertoraContext
|
|
34
|
-
import EVMVerifier.
|
|
34
|
+
import EVMVerifier.certoraContextAttributes as Attrs
|
|
35
35
|
from Shared import certoraValidateFuncs as Vf
|
|
36
36
|
from EVMVerifier import certoraContextValidator as Cv
|
|
37
|
-
import EVMVerifier.certoraContext as Ctx
|
|
38
37
|
from Shared import certoraUtils as Util
|
|
38
|
+
import EVMVerifier.certoraContext as Ctx
|
|
39
|
+
|
|
39
40
|
|
|
40
41
|
BUILD_IS_LIBRARY = False
|
|
41
42
|
AUTO_FINDER_PREFIX = "autoFinder_"
|
|
@@ -2804,7 +2805,8 @@ class CertoraBuildGenerator:
|
|
|
2804
2805
|
errs.append(e)
|
|
2805
2806
|
if len(errs) > 0:
|
|
2806
2807
|
raise Util.CertoraUserInputError(
|
|
2807
|
-
|
|
2808
|
+
"Some methods as specified via the `method` flag could not be found!"
|
|
2809
|
+
f"{Util.NEW_LINE}{Util.NEW_LINE.join(str(e) for e in errs)}"
|
|
2808
2810
|
)
|
|
2809
2811
|
|
|
2810
2812
|
# Build sources tree
|
|
@@ -3486,8 +3488,8 @@ class CertoraBuildGenerator:
|
|
|
3486
3488
|
if context.yul_abi:
|
|
3487
3489
|
sources.add(Path(context.yul_abi))
|
|
3488
3490
|
|
|
3489
|
-
if hasattr(context,
|
|
3490
|
-
|
|
3491
|
+
if hasattr(context, Attrs.EvmProverAttributes.PROVER_RESOURCE_FILES.get_conf_key()) \
|
|
3492
|
+
and context.prover_resource_files:
|
|
3491
3493
|
for value in context.prover_resource_files:
|
|
3492
3494
|
_, file_path = value.split(':')
|
|
3493
3495
|
add_to_sources(Path(file_path))
|
|
@@ -3657,10 +3659,7 @@ def build(context: CertoraContext, ignore_spec_syntax_check: bool = False) -> No
|
|
|
3657
3659
|
build_logger.warning(
|
|
3658
3660
|
"Local checks of CVL specification files disabled. It is recommended to enable the checks.")
|
|
3659
3661
|
else:
|
|
3660
|
-
|
|
3661
|
-
spec_check_exit_code = Util.run_local_spec_check(False, typechecker_arguments)
|
|
3662
|
-
if spec_check_exit_code != 0:
|
|
3663
|
-
raise Util.CertoraUserInputError("CVL specification syntax check failed")
|
|
3662
|
+
Ctx.run_local_spec_check(False, context)
|
|
3664
3663
|
|
|
3665
3664
|
certora_build_cache_manager = CertoraBuildCacheManager()
|
|
3666
3665
|
|
|
@@ -18,7 +18,7 @@ from EVMVerifier.certoraJobList import JobList
|
|
|
18
18
|
from EVMVerifier.certoraExtensionInfo import ExtensionInfoWriter
|
|
19
19
|
from EVMVerifier.certoraContextClass import CertoraContext
|
|
20
20
|
from Shared import certoraUtils as Util
|
|
21
|
-
import EVMVerifier.
|
|
21
|
+
import EVMVerifier.certoraContextAttributes as Attrs
|
|
22
22
|
import EVMVerifier.certoraContext as Ctx
|
|
23
23
|
from Shared import certoraValidateFuncs as Vf
|
|
24
24
|
from Mutate import mutateUtil as MutUtil
|
|
@@ -442,7 +442,7 @@ class CloudVerification:
|
|
|
442
442
|
self.presigned_url = ""
|
|
443
443
|
self.userId = -1
|
|
444
444
|
self.msg = ""
|
|
445
|
-
self.user_defined_cache = context.user_defined_cache
|
|
445
|
+
self.user_defined_cache = context.user_defined_cache if Attrs.is_evm_app() else None
|
|
446
446
|
self.expected_filename = context.expected_file
|
|
447
447
|
|
|
448
448
|
self.set_protocol_name_and_author(context)
|
|
@@ -577,7 +577,7 @@ class CloudVerification:
|
|
|
577
577
|
|
|
578
578
|
jar_settings = Ctx.collect_jar_args(self.context)
|
|
579
579
|
|
|
580
|
-
if
|
|
580
|
+
if Attrs.is_solana_app():
|
|
581
581
|
# We need to strip "../" path component from all file paths because
|
|
582
582
|
# unzip will also do that.
|
|
583
583
|
solana_jar_settings = []
|
|
@@ -597,7 +597,7 @@ class CloudVerification:
|
|
|
597
597
|
elif arg == '-solanaSummaries':
|
|
598
598
|
is_file = True
|
|
599
599
|
auth_data["jarSettings"] = solana_jar_settings
|
|
600
|
-
elif
|
|
600
|
+
elif Attrs.is_wasm_app():
|
|
601
601
|
# We need to strip "../" path component from all file paths because
|
|
602
602
|
# unzip will also do that.
|
|
603
603
|
wasm_jar_settings = []
|
|
@@ -610,7 +610,7 @@ class CloudVerification:
|
|
|
610
610
|
auth_data["jarSettings"] = jar_settings
|
|
611
611
|
|
|
612
612
|
if self.context.coinbase_mode:
|
|
613
|
-
auth_data["jarSettings"].append(
|
|
613
|
+
auth_data["jarSettings"].append(Attrs.EvmProverAttributes.COINBASE_MODE.jar_flag)
|
|
614
614
|
|
|
615
615
|
if self.context.java_args is not None:
|
|
616
616
|
auth_data["javaArgs"] = self.context.java_args.strip()
|
|
@@ -623,7 +623,7 @@ class CloudVerification:
|
|
|
623
623
|
|
|
624
624
|
auth_data["useLatestFe"] = self.context.fe_version == str(Util.FeValue.LATEST)
|
|
625
625
|
|
|
626
|
-
if self.context.cache is not None:
|
|
626
|
+
if Attrs.is_evm_app() and self.context.cache is not None:
|
|
627
627
|
auth_data["toolSceneCacheKey"] = self.context.cache
|
|
628
628
|
|
|
629
629
|
if self.context.msg is not None:
|
|
@@ -640,7 +640,7 @@ class CloudVerification:
|
|
|
640
640
|
if self.protocol_author:
|
|
641
641
|
auth_data["protocolAuthor"] = self.protocol_author
|
|
642
642
|
|
|
643
|
-
if self.context.verify:
|
|
643
|
+
if Attrs.is_evm_app() and self.context.verify:
|
|
644
644
|
auth_data["primaryContract"] = self.context.verify.split(':')[0]
|
|
645
645
|
cloud_logger.debug(f'authdata = {auth_data}')
|
|
646
646
|
|
|
@@ -714,7 +714,7 @@ class CloudVerification:
|
|
|
714
714
|
# We zip the tac file itself
|
|
715
715
|
result = compress_files(self.ZipFilePath, self.context.files[0],
|
|
716
716
|
short_output=Ctx.is_minimal_cli_output(self.context))
|
|
717
|
-
elif self.context.is_bytecode:
|
|
717
|
+
elif Attrs.is_evm_app() and self.context.is_bytecode:
|
|
718
718
|
# We zip the bytecode jsons and the spec
|
|
719
719
|
paths = []
|
|
720
720
|
for bytecode_json in self.context.bytecode_jsons:
|
|
@@ -722,7 +722,7 @@ class CloudVerification:
|
|
|
722
722
|
paths.append(Path(self.context.bytecode_spec))
|
|
723
723
|
result = compress_files(self.ZipFilePath, *paths,
|
|
724
724
|
short_output=Ctx.is_minimal_cli_output(self.context))
|
|
725
|
-
elif
|
|
725
|
+
elif Attrs.is_solana_app():
|
|
726
726
|
# We zip the ELF files and the two configuration files
|
|
727
727
|
jar_args = Ctx.collect_jar_args(self.context)
|
|
728
728
|
paths = []
|
|
@@ -739,7 +739,7 @@ class CloudVerification:
|
|
|
739
739
|
elif arg == '-solanaSummaries':
|
|
740
740
|
is_file = True
|
|
741
741
|
result = compress_files(self.ZipFilePath, *paths, short_output=Ctx.is_minimal_cli_output(self.context))
|
|
742
|
-
elif
|
|
742
|
+
elif Attrs.is_wasm_app():
|
|
743
743
|
# We zip the wat file
|
|
744
744
|
paths = []
|
|
745
745
|
for file in self.context.files:
|
{certora_cli-7.10.1 → certora_cli-7.14.2}/certora_cli/EVMVerifier/certoraCollectRunMetadata.py
RENAMED
|
@@ -16,6 +16,9 @@ from EVMVerifier.certoraContextClass import CertoraContext
|
|
|
16
16
|
metadata_logger = logging.getLogger("metadata")
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
def get_main_spec(context: CertoraContext) -> Optional[str]:
|
|
20
|
+
return getattr(context, 'spec_file', None) or getattr(context, 'bytecode_spec', None)
|
|
21
|
+
|
|
19
22
|
# jsonify sets as lists
|
|
20
23
|
class MetadataEncoder(json.JSONEncoder):
|
|
21
24
|
def default(self, obj: Any) -> Any:
|
|
@@ -128,14 +131,14 @@ def build_conf_path_relative(relative_cwd: Path, context: CertoraContext) -> Opt
|
|
|
128
131
|
return None
|
|
129
132
|
|
|
130
133
|
|
|
131
|
-
def collect_run_metadata(wd: Path, raw_args: List[str],
|
|
134
|
+
def collect_run_metadata(wd: Path, raw_args: List[str], context: CertoraContext) \
|
|
132
135
|
-> RunMetaData:
|
|
133
136
|
|
|
134
137
|
# This is a temporary hotfix to fix a bug on windows. If git does not exist on client calls to to_relative()
|
|
135
138
|
# cause exception and mess up paths
|
|
136
139
|
if Utils.is_windows():
|
|
137
140
|
return RunMetaData(raw_args=raw_args,
|
|
138
|
-
conf=
|
|
141
|
+
conf=context.conf_options,
|
|
139
142
|
origin="",
|
|
140
143
|
revision="",
|
|
141
144
|
branch="",
|
|
@@ -163,13 +166,13 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
163
166
|
cwd_relative = improvise_cwd_relative(wd)
|
|
164
167
|
conf_path = build_conf_path_relative(cwd_relative, context)
|
|
165
168
|
return RunMetaData(raw_args=raw_args,
|
|
166
|
-
conf=
|
|
169
|
+
conf=context.conf_options,
|
|
167
170
|
origin="",
|
|
168
171
|
revision="",
|
|
169
172
|
branch="",
|
|
170
173
|
cwd_relative=cwd_relative,
|
|
171
174
|
dirty=True,
|
|
172
|
-
main_spec=context
|
|
175
|
+
main_spec=get_main_spec(context),
|
|
173
176
|
conf_path=conf_path,
|
|
174
177
|
group_id=context.group_id)
|
|
175
178
|
|
|
@@ -198,13 +201,13 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
198
201
|
|
|
199
202
|
conf_path = build_conf_path_relative(cwd_relative, context)
|
|
200
203
|
data = RunMetaData(raw_args=raw_args,
|
|
201
|
-
conf=
|
|
204
|
+
conf=context.conf_options,
|
|
202
205
|
origin=origin,
|
|
203
206
|
revision=sha,
|
|
204
207
|
branch=branch_name,
|
|
205
208
|
cwd_relative=cwd_relative,
|
|
206
209
|
dirty=dirty,
|
|
207
|
-
main_spec=context
|
|
210
|
+
main_spec=get_main_spec(context),
|
|
208
211
|
conf_path=conf_path,
|
|
209
212
|
group_id=context.group_id)
|
|
210
213
|
|
|
@@ -216,12 +219,12 @@ def collect_run_metadata(wd: Path, raw_args: List[str], raw_input_conf_dict: Dic
|
|
|
216
219
|
cwd_relative = improvise_cwd_relative(wd)
|
|
217
220
|
conf_path = build_conf_path_relative(cwd_relative, context)
|
|
218
221
|
return RunMetaData(raw_args=raw_args,
|
|
219
|
-
conf=
|
|
222
|
+
conf=context.conf_options,
|
|
220
223
|
origin="",
|
|
221
224
|
revision="",
|
|
222
225
|
branch="",
|
|
223
226
|
cwd_relative=cwd_relative,
|
|
224
227
|
dirty=True,
|
|
225
|
-
main_spec=context
|
|
228
|
+
main_spec=get_main_spec(context),
|
|
226
229
|
conf_path=conf_path,
|
|
227
230
|
group_id=context.group_id)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import json5
|
|
2
2
|
import logging
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Dict, Any
|
|
4
|
+
from typing import Dict, Any
|
|
5
5
|
|
|
6
6
|
import EVMVerifier.certoraContext as Ctx
|
|
7
|
-
import EVMVerifier.
|
|
7
|
+
import EVMVerifier.certoraContextAttributes as Attrs
|
|
8
8
|
from EVMVerifier.certoraContextClass import CertoraContext
|
|
9
9
|
from Shared import certoraUtils as Util
|
|
10
10
|
|
|
@@ -31,11 +31,12 @@ def current_conf_to_file(context: CertoraContext) -> Dict[str, Any]:
|
|
|
31
31
|
4. Parsing the .conf file is simpler, as we can ignore the null case
|
|
32
32
|
"""
|
|
33
33
|
def input_arg_with_value(k: Any, v: Any) -> Any:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
all_keys = Attr.all_context_keys()
|
|
34
|
+
all_conf_names = Attrs.get_attribute_class().all_conf_names()
|
|
35
|
+
return v is not None and v is not False and k in all_conf_names
|
|
37
36
|
|
|
38
|
-
context_to_save =
|
|
37
|
+
context_to_save = {k: v for k, v in vars(context).items() if input_arg_with_value(k, v)}
|
|
38
|
+
all_conf_names = Attrs.get_attribute_class().all_conf_names()
|
|
39
|
+
context_to_save = dict(sorted(context_to_save.items(), key=lambda x: all_conf_names.index(x[0])))
|
|
39
40
|
context_to_save.pop('build_dir', None) # build dir should not be saved, each run should define its own build_dir
|
|
40
41
|
|
|
41
42
|
out_file_path = Util.get_last_conf_file()
|
|
@@ -45,16 +46,14 @@ def current_conf_to_file(context: CertoraContext) -> Dict[str, Any]:
|
|
|
45
46
|
return context_to_save
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
def read_from_conf_file(context: CertoraContext
|
|
49
|
+
def read_from_conf_file(context: CertoraContext) -> None:
|
|
49
50
|
"""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
@param context: A namespace containing options from the command line
|
|
53
|
-
.conf file when we call this method)
|
|
54
|
-
:param conf_file_path: Path to the conf file
|
|
51
|
+
If the file in the command line is a conf file, read data from the configuration file and add each key to the
|
|
52
|
+
context namespace if the key was not set in the command line (command line shadows conf data).
|
|
53
|
+
@param context: A namespace containing options from the command line
|
|
55
54
|
"""
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
|
|
56
|
+
conf_file_path = Path(context.files[0])
|
|
58
57
|
assert conf_file_path.suffix == ".conf", f"conf file must be of type .conf, instead got {conf_file_path}"
|
|
59
58
|
|
|
60
59
|
with conf_file_path.open() as conf_file:
|
|
@@ -66,21 +65,26 @@ def read_from_conf_file(context: CertoraContext, conf_file_path: Optional[Path]
|
|
|
66
65
|
context.conf_file = str(conf_file_path)
|
|
67
66
|
|
|
68
67
|
|
|
69
|
-
def check_conf_content(
|
|
68
|
+
def check_conf_content(conf: Dict[str, Any], context: CertoraContext) -> None:
|
|
70
69
|
"""
|
|
71
70
|
validating content read from the conf file
|
|
72
71
|
Note: a command line definition trumps the definition in the file.
|
|
73
72
|
If in the .conf file solc is 4.25 and in the command line --solc solc6.10 was given, sol6.10 will be used
|
|
74
|
-
@param
|
|
73
|
+
@param conf: A json object in the conf file format
|
|
75
74
|
@param context: A namespace containing options from the command line, if any
|
|
76
75
|
"""
|
|
77
|
-
for option in
|
|
76
|
+
for option in conf:
|
|
78
77
|
if hasattr(context, option):
|
|
79
78
|
val = getattr(context, option)
|
|
80
79
|
if val is None or val is False:
|
|
81
|
-
setattr(context, option,
|
|
80
|
+
setattr(context, option, conf[option])
|
|
81
|
+
elif option != Attrs.EvmProverAttributes.FILES.get_conf_key() and val != conf[option]:
|
|
82
|
+
cli_val = ' '.join(val) if isinstance(val, list) else str(val)
|
|
83
|
+
conf_val = ' '.join(conf[option]) if isinstance(conf[option], list) else str(conf[option])
|
|
84
|
+
run_logger.warning(f"Note: attribute {option} value in CLI ({cli_val}) overrides value stored in conf"
|
|
85
|
+
f" file ({conf_val})")
|
|
82
86
|
else:
|
|
83
87
|
raise Util.CertoraUserInputError(f"{option} appears in the conf file but is not a known attribute. ")
|
|
84
|
-
if 'files' not in
|
|
88
|
+
if 'files' not in conf:
|
|
85
89
|
raise Util.CertoraUserInputError("Mandatory 'files' attribute is missing from the configuration")
|
|
86
|
-
context.files =
|
|
90
|
+
context.files = conf['files'] # Override the current .conf file
|
|
@@ -6,7 +6,7 @@ import os
|
|
|
6
6
|
import re
|
|
7
7
|
import sys
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import Dict, List, Optional,
|
|
9
|
+
from typing import Dict, List, Optional, Any
|
|
10
10
|
from rich.console import Console
|
|
11
11
|
|
|
12
12
|
|
|
@@ -17,7 +17,7 @@ from EVMVerifier.certoraContextClass import CertoraContext
|
|
|
17
17
|
from Shared import certoraUtils as Util
|
|
18
18
|
from EVMVerifier.certoraConfigIO import read_from_conf_file, current_conf_to_file
|
|
19
19
|
import EVMVerifier.certoraContextValidator as Cv
|
|
20
|
-
import EVMVerifier.
|
|
20
|
+
import EVMVerifier.certoraContextAttributes as Attrs
|
|
21
21
|
from Shared import certoraValidateFuncs as Vf
|
|
22
22
|
from Shared import certoraAttrUtil as AttrUtil
|
|
23
23
|
|
|
@@ -37,31 +37,36 @@ def escape_string(string: str) -> str:
|
|
|
37
37
|
return f"\"{string}\""
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def get_attr_value(context: CertoraContext, attr:
|
|
40
|
+
def get_attr_value(context: CertoraContext, attr: AttrUtil.AttributeDefinition) -> Any:
|
|
41
41
|
conf_key = attr.get_conf_key()
|
|
42
42
|
return getattr(context, conf_key, None)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def collect_args_with_jar_flags(context: CertoraContext) -> List[
|
|
46
|
-
|
|
45
|
+
def collect_args_with_jar_flags(context: CertoraContext) -> List[AttrUtil.AttributeDefinition]:
|
|
46
|
+
attribute_list = Attrs.get_attribute_class().attribute_list()
|
|
47
|
+
return [attr for attr in attribute_list if get_attr_value(context, attr) and attr.jar_flag]
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
def collect_args_build_cache_affecting(context: CertoraContext) -> List[
|
|
50
|
-
|
|
50
|
+
def collect_args_build_cache_affecting(context: CertoraContext) -> List[AttrUtil.AttributeDefinition]:
|
|
51
|
+
attribute_list = Attrs.get_attribute_class().attribute_list()
|
|
52
|
+
return [attr for attr in attribute_list if get_attr_value(context, attr) and
|
|
53
|
+
attr.affects_build_cache_key]
|
|
51
54
|
|
|
52
55
|
|
|
53
|
-
def collect_args_build_cache_disabling(context: CertoraContext) -> List[
|
|
54
|
-
|
|
56
|
+
def collect_args_build_cache_disabling(context: CertoraContext) -> List[AttrUtil.AttributeDefinition]:
|
|
57
|
+
attribute_list = Attrs.get_attribute_class().attribute_list()
|
|
58
|
+
return [attr for attr in attribute_list if get_attr_value(context, attr) and
|
|
59
|
+
attr.disables_build_cache]
|
|
55
60
|
|
|
56
61
|
|
|
57
|
-
def create_jar_flag_list(context: CertoraContext, args: List[
|
|
62
|
+
def create_jar_flag_list(context: CertoraContext, args: List[AttrUtil.AttributeDefinition]) -> List[str]:
|
|
58
63
|
return_list = []
|
|
59
64
|
for arg in args:
|
|
60
65
|
attr = get_attr_value(context, arg)
|
|
61
|
-
jar_flag = arg.
|
|
66
|
+
jar_flag = arg.jar_flag
|
|
62
67
|
assert jar_flag is not None
|
|
63
68
|
return_list.append(jar_flag)
|
|
64
|
-
if not arg.
|
|
69
|
+
if not arg.jar_no_value:
|
|
65
70
|
if isinstance(attr, list):
|
|
66
71
|
return_list.append(','.join(attr))
|
|
67
72
|
elif isinstance(attr, bool):
|
|
@@ -82,7 +87,7 @@ def collect_jar_args(context: CertoraContext) -> List[str]:
|
|
|
82
87
|
"""
|
|
83
88
|
return_list = create_jar_flag_list(context, collect_args_with_jar_flags(context))
|
|
84
89
|
|
|
85
|
-
prover_args_values = getattr(context,
|
|
90
|
+
prover_args_values = getattr(context, Attrs.EvmProverAttributes.PROVER_ARGS.get_conf_key(), None)
|
|
86
91
|
if prover_args_values:
|
|
87
92
|
for value in prover_args_values:
|
|
88
93
|
return_list.extend(value.split())
|
|
@@ -93,7 +98,7 @@ def collect_jar_args(context: CertoraContext) -> List[str]:
|
|
|
93
98
|
# will permit Solidity function calls in CVL quantifier bodies. We prioritize the type checker jar
|
|
94
99
|
# argument "typechecker_args" in the conf files and if it contains the flag "-allowSolidityQuantifierCalls true"
|
|
95
100
|
# we append the prover argument version to the list of prover jar arguments.
|
|
96
|
-
type_checker_values = getattr(context,
|
|
101
|
+
type_checker_values = getattr(context, Attrs.EvmProverAttributes.TYPECHECKER_ARGS.get_conf_key(), None)
|
|
97
102
|
if type_checker_values:
|
|
98
103
|
for value in type_checker_values:
|
|
99
104
|
values = value.split()
|
|
@@ -102,24 +107,22 @@ def collect_jar_args(context: CertoraContext) -> List[str]:
|
|
|
102
107
|
return return_list
|
|
103
108
|
|
|
104
109
|
|
|
105
|
-
def get_typechecker_arguments(context: CertoraContext
|
|
110
|
+
def get_typechecker_arguments(context: CertoraContext) -> List[str]:
|
|
106
111
|
"""
|
|
107
112
|
Assembles a string of all the command-line options the typechecker cares about
|
|
108
113
|
@param context: The context
|
|
109
|
-
@param typechecker_args: A dict of additional options (as provided via "typechecker_args" in a conf file)
|
|
110
114
|
@return: A string with all the options in the format the typechecker understands.
|
|
111
115
|
"""
|
|
112
|
-
|
|
113
|
-
if typechecker_args:
|
|
114
|
-
|
|
116
|
+
args = []
|
|
117
|
+
if context.typechecker_args:
|
|
118
|
+
args += context.typechecker_args
|
|
115
119
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
args_list = create_jar_flag_list(context, list(relevant_args))
|
|
120
|
+
relevant_attrs = filter(lambda arg: get_attr_value(context, arg),
|
|
121
|
+
[Attrs.EvmProverAttributes.RULE, Attrs.EvmProverAttributes.EXCLUDE_RULE,
|
|
122
|
+
Attrs.EvmProverAttributes.FOUNDRY_TESTS_MODE])
|
|
123
|
+
args += create_jar_flag_list(context, list(relevant_attrs))
|
|
121
124
|
|
|
122
|
-
return
|
|
125
|
+
return args
|
|
123
126
|
|
|
124
127
|
|
|
125
128
|
def get_local_run_cmd(context: CertoraContext) -> str:
|
|
@@ -129,9 +132,9 @@ def get_local_run_cmd(context: CertoraContext) -> str:
|
|
|
129
132
|
@return: A command for running the prover locally
|
|
130
133
|
"""
|
|
131
134
|
run_args = []
|
|
132
|
-
if context.is_tac or
|
|
135
|
+
if context.is_tac or Attrs.is_solana_app() or Attrs.is_wasm_app():
|
|
133
136
|
run_args.append(context.files[0])
|
|
134
|
-
if context.cache is not None:
|
|
137
|
+
if Attrs.is_evm_app() and context.cache is not None:
|
|
135
138
|
run_args.extend(['-cache', context.cache])
|
|
136
139
|
|
|
137
140
|
jar_args = collect_jar_args(context)
|
|
@@ -163,7 +166,7 @@ def get_local_run_cmd(context: CertoraContext) -> str:
|
|
|
163
166
|
return cmd
|
|
164
167
|
|
|
165
168
|
|
|
166
|
-
class ProverParser(AttrUtil.
|
|
169
|
+
class ProverParser(AttrUtil.ContextAttributeParser):
|
|
167
170
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
168
171
|
super().__init__(*args, **kwargs)
|
|
169
172
|
|
|
@@ -184,13 +187,12 @@ class ProverParser(AttrUtil.CertoraArgumentParser):
|
|
|
184
187
|
console.print("3. list (L): gets multiple strings as a value, flags may also appear multiple times")
|
|
185
188
|
console.print("4. map (M): collection of key, value pairs\n\n")
|
|
186
189
|
|
|
187
|
-
|
|
190
|
+
Attrs.EvmProverAttributes.print_attr_help()
|
|
188
191
|
console.print("\n\nYou can find detailed documentation of the supported flags here: "
|
|
189
192
|
f"{Util.print_rich_link(CLI_DOCUMENTATION_URL)}\n\n")
|
|
190
193
|
|
|
191
194
|
return ''
|
|
192
195
|
|
|
193
|
-
|
|
194
196
|
def __get_argparser() -> argparse.ArgumentParser:
|
|
195
197
|
def formatter(prog: Any) -> argparse.HelpFormatter:
|
|
196
198
|
return argparse.HelpFormatter(prog, max_help_position=100, width=200)
|
|
@@ -200,19 +202,15 @@ def __get_argparser() -> argparse.ArgumentParser:
|
|
|
200
202
|
epilog=" -*-*-* You can find detailed documentation of the supported options in "
|
|
201
203
|
f"{CLI_DOCUMENTATION_URL} -*-*-*")
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
for arg in args:
|
|
205
|
+
for arg in Attrs.get_attribute_class().attribute_list():
|
|
206
206
|
flag = arg.get_flag()
|
|
207
|
-
parser.add_argument(flag, help=arg.
|
|
207
|
+
parser.add_argument(flag, help=arg.help_msg, **arg.argparse_args)
|
|
208
208
|
return parser
|
|
209
209
|
|
|
210
210
|
|
|
211
|
-
def get_args(args_list: Optional[List[str]] = None) ->
|
|
211
|
+
def get_args(args_list: Optional[List[str]] = None) -> CertoraContext:
|
|
212
212
|
"""
|
|
213
213
|
Compiles an argparse.Namespace from the given list of command line arguments.
|
|
214
|
-
Additionally returns the prettified dictionary version of the input arguments as generated by current_conf_to_file
|
|
215
|
-
and printed to the .conf file in .lastConfs.
|
|
216
214
|
|
|
217
215
|
Why do we handle --version before argparse?
|
|
218
216
|
Because on some platforms, mainly CI tests, we cannot fetch the installed distribution package version of
|
|
@@ -220,6 +218,8 @@ def get_args(args_list: Optional[List[str]] = None) -> Tuple[CertoraContext, Dic
|
|
|
220
218
|
We do it pre-argparse, because we do not care bout the input validity of anything else if we have a --version flag
|
|
221
219
|
"""
|
|
222
220
|
|
|
221
|
+
if not Attrs.ATTRIBUTES_CLASS:
|
|
222
|
+
Attrs.set_attribute_class(Attrs.EvmProverAttributes) # for scripts that call get_args directly
|
|
223
223
|
if args_list is None:
|
|
224
224
|
args_list = sys.argv
|
|
225
225
|
|
|
@@ -249,20 +249,30 @@ def get_args(args_list: Optional[List[str]] = None) -> Tuple[CertoraContext, Dic
|
|
|
249
249
|
if context.is_conf:
|
|
250
250
|
read_from_conf_file(context)
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
context.local = Util.is_local(context)
|
|
253
|
+
context.is_tac = context.files and context.files[0].endswith('.tac')
|
|
254
|
+
context.is_vyper = context.files and context.files[0].endswith('.vy')
|
|
255
|
+
|
|
256
|
+
if Attrs.is_evm_app():
|
|
257
|
+
Cv.check_mode_of_operation(context) # Here boolean run characteristics are set
|
|
253
258
|
|
|
254
259
|
validator = Cv.CertoraContextValidator(context)
|
|
255
260
|
validator.validate()
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
261
|
+
if Attrs.is_evm_app():
|
|
262
|
+
current_build_directory = Util.get_build_dir()
|
|
263
|
+
if context.build_dir is not None and current_build_directory != context.build_dir:
|
|
264
|
+
Util.reset_certora_internal_dir(context.build_dir)
|
|
265
|
+
os.rename(current_build_directory, context.build_dir)
|
|
260
266
|
|
|
261
267
|
# Store current options (including the ones read from .conf file)
|
|
262
|
-
conf_options = current_conf_to_file(context)
|
|
268
|
+
context.conf_options = current_conf_to_file(context)
|
|
269
|
+
|
|
270
|
+
if context.java_args is not None:
|
|
271
|
+
context.java_args = ' '.join(context.java_args).replace('"', '').replace("'", '')
|
|
263
272
|
|
|
264
|
-
|
|
265
|
-
|
|
273
|
+
if Attrs.is_evm_app():
|
|
274
|
+
validator.check_args_post_argparse()
|
|
275
|
+
setup_cache(context) # Here context.cache, context.user_defined_cache are set
|
|
266
276
|
|
|
267
277
|
# Setup defaults (defaults are not recorded in conf file)
|
|
268
278
|
context.expected_file = context.expected_file or "expected.json"
|
|
@@ -273,7 +283,7 @@ def get_args(args_list: Optional[List[str]] = None) -> Tuple[CertoraContext, Dic
|
|
|
273
283
|
|
|
274
284
|
if context.test == str(Util.TestValue.CHECK_ARGS):
|
|
275
285
|
raise Util.TestResultsReady(context)
|
|
276
|
-
return context
|
|
286
|
+
return context
|
|
277
287
|
|
|
278
288
|
|
|
279
289
|
def get_client_version() -> str:
|
|
@@ -340,7 +350,8 @@ def format_input(context: CertoraContext) -> None:
|
|
|
340
350
|
:param context: Namespace containing all command line arguments, generated by get_args()
|
|
341
351
|
"""
|
|
342
352
|
flatten_arg_lists(context)
|
|
343
|
-
|
|
353
|
+
if Attrs.is_evm_app():
|
|
354
|
+
__dedup_link(context)
|
|
344
355
|
|
|
345
356
|
|
|
346
357
|
def flatten_arg_lists(context: CertoraContext) -> None:
|
|
@@ -364,7 +375,8 @@ def flatten_arg_lists(context: CertoraContext) -> None:
|
|
|
364
375
|
|
|
365
376
|
def __dedup_link(context: CertoraContext) -> None:
|
|
366
377
|
try:
|
|
367
|
-
|
|
378
|
+
if hasattr(context, 'link'):
|
|
379
|
+
context.link = list(set(context.link))
|
|
368
380
|
except TypeError:
|
|
369
381
|
pass
|
|
370
382
|
|
|
@@ -433,8 +445,7 @@ def handle_flags_in_args(args: List[str]) -> None:
|
|
|
433
445
|
Will all be converted to " -d"
|
|
434
446
|
|
|
435
447
|
"""
|
|
436
|
-
|
|
437
|
-
all_flags = list(map(lambda member: member.get_flag(), Attr.ContextAttribute))
|
|
448
|
+
all_flags = list(map(lambda member: member.get_flag(), Attrs.get_attribute_class().attribute_list()))
|
|
438
449
|
|
|
439
450
|
def surrounded(string: str, char: str) -> bool:
|
|
440
451
|
if len(string) < 2:
|
|
@@ -450,7 +461,7 @@ def handle_flags_in_args(args: List[str]) -> None:
|
|
|
450
461
|
arg = arg[1:-1]
|
|
451
462
|
else:
|
|
452
463
|
break
|
|
453
|
-
if len(arg) > 0 and arg[0] == '-' and (args[index - 1] ==
|
|
464
|
+
if len(arg) > 0 and arg[0] == '-' and (args[index - 1] == Attrs.EvmProverAttributes.JAVA_ARGS.get_flag()):
|
|
454
465
|
arg = f" {arg}"
|
|
455
466
|
if arg != args[index]:
|
|
456
467
|
args[index] = arg
|
|
@@ -483,3 +494,48 @@ def __rename_key(context: CertoraContext, old_key: str, new_key: str) -> None:
|
|
|
483
494
|
value = getattr(context, old_key)
|
|
484
495
|
setattr(context, new_key, value)
|
|
485
496
|
context.delete_key(old_key)
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def run_typechecker(typechecker_name: str, with_typechecking: bool, args: List[str]) -> None:
|
|
500
|
+
"""
|
|
501
|
+
Runs a spec typechecker or syntax checker
|
|
502
|
+
@param typechecker_name - the name of the jar that we should run for running typechecking
|
|
503
|
+
@param with_typechecking - True if we want full typechecking including build (Solidity outputs) file,
|
|
504
|
+
False if we run only the leaner syntax checking.
|
|
505
|
+
@param args: A list of strings of additional arguments to the typechecker jar.
|
|
506
|
+
|
|
507
|
+
"""
|
|
508
|
+
# Find path to typechecker jar
|
|
509
|
+
path_to_typechecker = Util.find_jar(typechecker_name)
|
|
510
|
+
|
|
511
|
+
context_logger.debug(f"Path to typechecker is {path_to_typechecker}")
|
|
512
|
+
# if typechecker jar does not exist, we just skip this step
|
|
513
|
+
if not path_to_typechecker.is_file():
|
|
514
|
+
raise Util.CertoraUserInputError(f"Could not run type checker locally: file not found {path_to_typechecker}")
|
|
515
|
+
|
|
516
|
+
# args to typechecker
|
|
517
|
+
typecheck_cmd = f"java -jar {path_to_typechecker} " \
|
|
518
|
+
f'-buildDirectory "{Util.get_build_dir().resolve()}" ' \
|
|
519
|
+
f"{'-typeCheck ' if with_typechecking else ''}" \
|
|
520
|
+
f"{' '.join(args)}"
|
|
521
|
+
|
|
522
|
+
exit_code = Util.run_jar_cmd(typecheck_cmd, False, custom_error_message="Failed to compile spec files:",
|
|
523
|
+
logger_topic="type_check")
|
|
524
|
+
if exit_code != 0:
|
|
525
|
+
raise Util.CertoraUserInputError("CVL specification syntax and type check failed")
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
def run_local_spec_check(with_typechecking: bool, context: CertoraContext) -> None:
|
|
529
|
+
"""
|
|
530
|
+
Runs the local type checker in one of two modes: (1) syntax only,
|
|
531
|
+
and (2) including full typechecking after building the contracts
|
|
532
|
+
"""
|
|
533
|
+
|
|
534
|
+
if context.disable_local_typechecking or Util.is_ci_or_git_action():
|
|
535
|
+
return
|
|
536
|
+
args = get_typechecker_arguments(context)
|
|
537
|
+
if Util.is_java_installed():
|
|
538
|
+
run_typechecker("Typechecker.jar", with_typechecking, args)
|
|
539
|
+
else:
|
|
540
|
+
raise Util.CertoraUserInputError("Cannot run local checks because of missing a suitable java installtion. "
|
|
541
|
+
"To skip local checks run with the --disable_local_typechecking flag")
|