certora-cli-beta-mirror 7.30.1__tar.gz → 8.0.0__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.
Files changed (87) hide show
  1. {certora_cli_beta_mirror-7.30.1/certora_cli_beta_mirror.egg-info → certora_cli_beta_mirror-8.0.0}/PKG-INFO +4 -3
  2. certora_cli_beta_mirror-8.0.0/README.md +1 -0
  3. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorFactory.py +11 -2
  4. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraBuild.py +68 -62
  5. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraBuildCacheManager.py +17 -16
  6. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraBuildRust.py +33 -21
  7. certora_cli_beta_mirror-7.30.1/certora_cli/Shared/rustProverCommon.py → certora_cli_beta_mirror-8.0.0/certora_cli/CertoraProver/certoraBuildSui.py +24 -18
  8. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraCloudIO.py +42 -33
  9. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraCollectConfigurationLayout.py +62 -51
  10. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraCollectRunMetadata.py +20 -5
  11. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraConfigIO.py +17 -14
  12. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraContext.py +62 -10
  13. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraContextAttributes.py +132 -203
  14. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraContextValidator.py +108 -101
  15. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraParseBuildScript.py +4 -3
  16. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraVerifyGenerator.py +9 -4
  17. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/splitRules.py +2 -0
  18. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/storageExtension.py +0 -35
  19. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/mutateApp.py +16 -10
  20. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/mutateAttributes.py +11 -0
  21. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/certoraAttrUtil.py +11 -5
  22. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/certoraUtils.py +50 -47
  23. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/certoraValidateFuncs.py +29 -15
  24. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/proverCommon.py +6 -2
  25. certora_cli_beta_mirror-8.0.0/certora_cli/certoraCVLFormatter.py +76 -0
  26. certora_cli_beta_mirror-8.0.0/certora_cli/certoraConcord.py +39 -0
  27. certora_cli_beta_mirror-8.0.0/certora_cli/certoraRun.py +178 -0
  28. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraSolanaProver.py +1 -1
  29. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraSorobanProver.py +1 -1
  30. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0/certora_cli_beta_mirror.egg-info}/PKG-INFO +4 -3
  31. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli_beta_mirror.egg-info/SOURCES.txt +4 -1
  32. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli_beta_mirror.egg-info/entry_points.txt +1 -0
  33. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli_beta_mirror.egg-info/requires.txt +1 -0
  34. certora_cli_beta_mirror-8.0.0/certora_jars/ASTExtraction.jar +0 -0
  35. certora_cli_beta_mirror-8.0.0/certora_jars/CERTORA-CLI-VERSION-METADATA.json +1 -0
  36. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_jars/Typechecker.jar +0 -0
  37. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/setup.py +6 -5
  38. certora_cli_beta_mirror-7.30.1/README.md +0 -1
  39. certora_cli_beta_mirror-7.30.1/certora_cli/certoraRun.py +0 -216
  40. certora_cli_beta_mirror-7.30.1/certora_jars/CERTORA-CLI-VERSION-METADATA.json +0 -1
  41. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/LICENSE +0 -0
  42. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/MANIFEST.in +0 -0
  43. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_bins/__init__.py +0 -0
  44. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollector.py +0 -0
  45. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorSol.py +0 -0
  46. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorSolBased.py +0 -0
  47. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorVy.py +0 -0
  48. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/CompilerCollectorYul.py +0 -0
  49. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/Compiler/__init__.py +0 -0
  50. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/__init__.py +0 -0
  51. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraBuildDataClasses.py +0 -0
  52. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraCompilerParameters.py +0 -0
  53. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraContextClass.py +0 -0
  54. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraContractFuncs.py +0 -0
  55. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraExtensionInfo.py +0 -0
  56. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraJobList.py +0 -0
  57. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraMiniSpecParser.py +0 -0
  58. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraNodeFilters.py +0 -0
  59. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraProjectScanner.py +0 -0
  60. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraSourceFinders.py +0 -0
  61. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/certoraType.py +0 -0
  62. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/CertoraProver/erc7201.py +0 -0
  63. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/Eq_default.conf +0 -0
  64. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/Eq_mc_no_out_template.spec +0 -0
  65. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/Eq_mc_template.spec +0 -0
  66. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/Eq_sanity.conf +0 -0
  67. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/Eq_template.spec +0 -0
  68. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/__init__.py +0 -0
  69. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/equivCheck.py +0 -0
  70. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/EquivalenceCheck/sanity.spec +0 -0
  71. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/__init__.py +0 -0
  72. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/mutateConstants.py +0 -0
  73. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/mutateUtil.py +0 -0
  74. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Mutate/mutateValidate.py +0 -0
  75. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/ExpectedComparator.py +0 -0
  76. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/__init__.py +0 -0
  77. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/Shared/certoraLogging.py +0 -0
  78. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/__init__.py +0 -0
  79. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraEVMProver.py +0 -0
  80. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraEqCheck.py +0 -0
  81. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraMutate.py +0 -0
  82. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/certoraRanger.py +0 -0
  83. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli/rustMutator.py +0 -0
  84. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli_beta_mirror.egg-info/dependency_links.txt +0 -0
  85. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_cli_beta_mirror.egg-info/top_level.txt +0 -0
  86. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/certora_jars/__init__.py +0 -0
  87. {certora_cli_beta_mirror-7.30.1 → certora_cli_beta_mirror-8.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: certora-cli-beta-mirror
3
- Version: 7.30.1
3
+ Version: 8.0.0
4
4
  Summary: Runner for the Certora Prover
5
5
  Home-page: https://pypi.org/project/certora-cli-beta-mirror
6
6
  Author: Certora
@@ -11,7 +11,7 @@ Project-URL: Source, https://github.com/Certora/CertoraProver
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
13
13
  Classifier: Operating System :: OS Independent
14
- Requires-Python: >=3.8
14
+ Requires-Python: >=3.9
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
17
  Requires-Dist: click
@@ -25,6 +25,7 @@ Requires-Dist: tqdm
25
25
  Requires-Dist: StrEnum
26
26
  Requires-Dist: universalmutator
27
27
  Requires-Dist: jinja2
28
+ Requires-Dist: wcmatch
28
29
  Dynamic: author
29
30
  Dynamic: author-email
30
31
  Dynamic: classifier
@@ -37,4 +38,4 @@ Dynamic: requires-dist
37
38
  Dynamic: requires-python
38
39
  Dynamic: summary
39
40
 
40
- Commit 5c9b8e0. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
41
+ Commit 852805e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -0,0 +1 @@
1
+ Commit 852805e. Build and Run scripts for executing the Certora Prover on Solidity smart contracts.
@@ -25,8 +25,9 @@ from CertoraProver.Compiler.CompilerCollector import CompilerLang, CompilerColle
25
25
  from CertoraProver.Compiler.CompilerCollectorSol import CompilerCollectorSol, CompilerLangSol
26
26
  from CertoraProver.Compiler.CompilerCollectorYul import CompilerLangYul, CompilerCollectorYul
27
27
  from CertoraProver.Compiler.CompilerCollectorVy import CompilerCollectorVy, CompilerLangVy
28
- from Shared.certoraUtils import match_path_to_mapping_key, remove_file, get_certora_config_dir
28
+ from Shared.certoraUtils import remove_file, get_certora_config_dir
29
29
  from CertoraProver.certoraContextClass import CertoraContext
30
+ import CertoraProver.certoraContext as Ctx
30
31
 
31
32
  # logger for running the Solidity compiler and reporting any errors it emits
32
33
  compiler_logger = logging.getLogger("compiler")
@@ -42,8 +43,16 @@ def get_relevant_compiler(contract_file_path: Path, context: CertoraContext) ->
42
43
 
43
44
  if contract_file_path.is_absolute():
44
45
  contract_file_path = Path(os.path.relpath(contract_file_path, Path.cwd()))
46
+
47
+ # If the contract file is in the sources directory, we want to use the relative path from the "cwd" in the source tree.
48
+ if Util.get_certora_sources_dir() in contract_file_path.parents:
49
+ cwd_in_source = Util.get_certora_sources_dir() / context.cwd_rel_in_sources
50
+ contract_file_path = Path(os.path.relpath(contract_file_path, cwd_in_source))
51
+
45
52
  if context.compiler_map:
46
- match = match_path_to_mapping_key(contract_file_path, context.compiler_map)
53
+ match = Ctx.get_map_attribute_value(context, contract_file_path, 'compiler')
54
+ assert isinstance(match, str), (f"In the attribute compiler_map, {contract_file_path} expected to be matched "
55
+ f"to a string, {match} is of type {type(match)} not a string")
47
56
  if match:
48
57
  return match
49
58
  else:
@@ -39,8 +39,6 @@ from CertoraProver.certoraSourceFinders import add_source_finders
39
39
  from CertoraProver.certoraVerifyGenerator import CertoraVerifyGenerator
40
40
  from CertoraProver.certoraContractFuncs import Func, InternalFunc, STATEMUT, SourceBytes
41
41
 
42
- from Shared.certoraUtils import is_relative_to
43
-
44
42
  scripts_dir_path = Path(__file__).parent.parent.resolve() # containing directory
45
43
  sys.path.insert(0, str(scripts_dir_path))
46
44
  from CertoraProver.Compiler.CompilerCollector import CompilerLang, CompilerCollector
@@ -450,8 +448,12 @@ def convert_pathname_to_posix(json_dict: Dict[str, Any], entry: str, smart_contr
450
448
  if path_obj.is_file():
451
449
  json_dict_posix_paths[path_obj.as_posix()] = json_dict[entry][file_path]
452
450
  else:
453
- fatal_error(compiler_logger, f"The path of the source file {file_path}"
454
- f"in the standard json file {json_dict} does not exist")
451
+ json_dict_str = str(json_dict)
452
+ # protecting against long strings
453
+ if len(json_dict_str) > 200:
454
+ json_dict_str = json_dict_str[:200] + '...'
455
+ fatal_error(compiler_logger, f"The path of the source file {file_path} "
456
+ f"in the standard json file does not exist!\n{json_dict_str} ")
455
457
  json_dict[entry] = json_dict_posix_paths
456
458
 
457
459
 
@@ -1361,46 +1363,48 @@ class CertoraBuildGenerator:
1361
1363
 
1362
1364
  return bytecode
1363
1365
 
1364
- def _handle_via_ir(self, contract_file_path: str, settings_dict: Dict[str, Any]) -> None:
1365
- if not self.context.solc_via_ir_map and not self.context.solc_via_ir:
1366
- return
1367
- if self.context.solc_via_ir_map:
1368
- match = Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_via_ir_map)
1369
- if match:
1370
- settings_dict["viaIR"] = match
1371
- elif self.context.solc_via_ir:
1366
+ def get_solc_via_ir_value(self, contract_file_path: Path) -> bool:
1367
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_via_ir')
1368
+ assert isinstance(match, (bool, type(None))), f"Expected solc_via_ir to be bool or None, got {type(match)}"
1369
+ return bool(match)
1370
+
1371
+ def get_solc_evm_version_value(self, contract_file_path: Path) -> Optional[str]:
1372
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_evm_version')
1373
+ assert isinstance(match, (str, type(None))), f"Expected solc_evm_version to be string or None, got {type(match)}"
1374
+ return match
1375
+
1376
+ def get_solc_optimize_value(self, contract_file_path: Path) -> Optional[str]:
1377
+ match = Ctx.get_map_attribute_value(self.context, contract_file_path, 'solc_optimize')
1378
+ assert isinstance(match, (str, type(None))), f"Expected solc_optimize to be string or None, got {type(match)}"
1379
+ return match
1380
+
1381
+ def _handle_via_ir(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1382
+ if self.get_solc_via_ir_value(contract_file_path):
1372
1383
  settings_dict["viaIR"] = True
1373
1384
 
1374
- def _handle_evm_version(self, contract_file_path: str, settings_dict: Dict[str, Any]) -> None:
1375
- if self.context.solc_evm_version_map:
1376
- match = Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_evm_version_map)
1377
- if match:
1378
- settings_dict["evmVersion"] = match
1379
- elif self.context.solc_evm_version:
1380
- settings_dict["evmVersion"] = self.context.solc_evm_version
1385
+ def _handle_evm_version(self, contract_file_path: Path, settings_dict: Dict[str, Any]) -> None:
1386
+ match = self.get_solc_evm_version_value(contract_file_path)
1387
+ if match:
1388
+ settings_dict["evmVersion"] = match
1381
1389
 
1382
- def _handle_optimize(self, contract_file_path: str, settings_dict: Dict[str, Any],
1390
+ def _handle_optimize(self, contract_file_path: Path, settings_dict: Dict[str, Any],
1383
1391
  compiler_collector: CompilerCollector) -> None:
1384
1392
  """
1385
1393
  @param contract_file_path: the contract that we are working on
1386
1394
  @param settings_dict: data structure for sending to the solc compiler
1387
1395
  """
1388
- if self.context.solc_optimize_map:
1389
- match = Util.match_path_to_mapping_key(Path(contract_file_path), self.context.solc_optimize_map)
1390
- if match and int(match) > 0:
1391
- settings_dict["optimizer"] = {"enabled": True}
1392
- settings_dict["optimizer"]['runs'] = int(match)
1393
- elif self.context.solc_optimize:
1396
+ match = self.get_solc_optimize_value(contract_file_path)
1397
+ if match:
1394
1398
  settings_dict["optimizer"] = {"enabled": True}
1395
- if int(self.context.solc_optimize) > 0:
1396
- settings_dict["optimizer"]['runs'] = int(self.context.solc_optimize)
1399
+ if int(match) > 0:
1400
+ settings_dict["optimizer"]['runs'] = int(match)
1397
1401
 
1398
1402
  # if optimizer is true, we should also define settings_dict["optimizer"]["details"]
1399
1403
  # for both optimize map and optimize
1400
1404
  optimizer = settings_dict.get("optimizer")
1401
1405
  if optimizer and isinstance(optimizer, dict) and optimizer.get('enabled'):
1402
1406
  # if we are not disabling finder friendly optimizer specifically, enable it whenever viaIR is also enabled
1403
- if not self.context.strict_solc_optimizer and self.context.solc_via_ir:
1407
+ if not self.context.strict_solc_optimizer and self.get_solc_via_ir_value(contract_file_path):
1404
1408
  # The default optimizer steps (taken from libsolidity/interface/OptimiserSettings.h) but with the
1405
1409
  # full inliner step removed
1406
1410
  solc0_8_26_to_0_8_30 = ("dhfoDgvulfnTUtnIfxa[r]EscLMVcul[j]Trpeulxa[r]cLCTUca[r]LSsTFOtfDnca[r]" +
@@ -1426,13 +1430,18 @@ class CertoraBuildGenerator:
1426
1430
  compiler_version = compiler_collector.compiler_version
1427
1431
  major, minor, patch = compiler_version
1428
1432
 
1429
- err_msg = "--finder_friendly_optimizer option supports solc versions 0.6.7 - 0.8.25 only, " \
1430
- f"got {major}.{minor}.{patch}"
1433
+ err_msg = \
1434
+ f"Unsupported solc version {major}.{minor}.{patch} for `solc_via_ir`. " \
1435
+ f"Supported versions: 0.6.7 – 0.8.25.\n" \
1436
+ f"Use `solc_via_ir_map` to disable `solc_via_ir` for specific files with older compiler versions."
1437
+
1431
1438
  yul_optimizer_steps = None
1432
1439
  if major != 0:
1433
1440
  raise Util.CertoraUserInputError(err_msg)
1434
1441
  elif minor < 6 or (minor == 6 and patch < 7):
1435
1442
  raise Util.CertoraUserInputError(err_msg)
1443
+ elif self.context.yul_optimizer_steps:
1444
+ yul_optimizer_steps = self.context.yul_optimizer_steps
1436
1445
  elif (minor == 6 and patch >= 7) or (minor == 7 and 0 <= patch <= 1):
1437
1446
  yul_optimizer_steps = solc0_6_7_to_0_7_1
1438
1447
  elif minor == 7 and 2 <= patch <= 5:
@@ -1470,7 +1479,7 @@ class CertoraBuildGenerator:
1470
1479
  for opt_pass in self.context.disable_solc_optimizers:
1471
1480
  settings_dict["optimizer"]["details"][opt_pass] = False
1472
1481
 
1473
- def _fill_codegen_related_options(self, contract_file_path: str, settings_dict: Dict[str, Any],
1482
+ def _fill_codegen_related_options(self, contract_file_path: Path, settings_dict: Dict[str, Any],
1474
1483
  compiler_collector: CompilerCollector) -> None:
1475
1484
  """
1476
1485
  Fills options that control how we call solc and affect the bytecode in some way
@@ -1551,7 +1560,7 @@ class CertoraBuildGenerator:
1551
1560
  }
1552
1561
  }
1553
1562
 
1554
- self._fill_codegen_related_options(contract_file_as_provided, settings_dict, compiler_collector)
1563
+ self._fill_codegen_related_options(Path(contract_file_as_provided), settings_dict, compiler_collector)
1555
1564
 
1556
1565
  result_dict = {"language": compiler_collector_lang.name, "sources": sources_dict, "settings": settings_dict}
1557
1566
  # debug_print("Standard json input")
@@ -2286,7 +2295,7 @@ class CertoraBuildGenerator:
2286
2295
 
2287
2296
  if compiler_lang == CompilerLangSol():
2288
2297
  settings_dict: Dict[str, Any] = {}
2289
- self._fill_codegen_related_options(build_arg_contract_file, settings_dict,
2298
+ self._fill_codegen_related_options(Path(build_arg_contract_file), settings_dict,
2290
2299
  compiler_collector_for_contract_file)
2291
2300
  solc_optimizer_on, solc_optimizer_runs = self.solc_setting_optimizer_runs(settings_dict)
2292
2301
  solc_via_ir = self.solc_setting_via_ir(settings_dict)
@@ -2416,7 +2425,7 @@ class CertoraBuildGenerator:
2416
2425
  # if no function finder mode set, determine based on viaIR enabled or not:
2417
2426
  if self.context.function_finder_mode is None:
2418
2427
  # in via-ir, should not compress
2419
- if self.context.solc_via_ir:
2428
+ if self.get_solc_via_ir_value(Path(contract_file)):
2420
2429
  should_compress = False
2421
2430
  else:
2422
2431
  should_compress = True
@@ -2682,7 +2691,7 @@ class CertoraBuildGenerator:
2682
2691
  self.handle_erc7201_annotations()
2683
2692
  self.handle_storage_extension_harnesses()
2684
2693
 
2685
- def extract_slayout(self, original_file: str, ns_storage: Set[NameSpacedStorage]) -> NewStorageInfo:
2694
+ def extract_slayout(self, original_file: str, ns_storage: Set[NameSpacedStorage], compiler_version: str) -> NewStorageInfo:
2686
2695
  """
2687
2696
  Given a file containing a contract with namespaced storage, extract the storage information
2688
2697
  corresponding to the namespaced types.
@@ -2707,7 +2716,9 @@ class CertoraBuildGenerator:
2707
2716
  # original file is accessed also in the actual code, and compiling it
2708
2717
  # directly can cause issues.
2709
2718
  tmp_file.write(f"import \"{original_file}\";\n\n")
2710
-
2719
+ rel_path = os.path.relpath(tmp_file.name, Path.cwd())
2720
+ if self.context.compiler_map:
2721
+ self.context.compiler_map.update({rel_path: compiler_version}, last=False)
2711
2722
  # Write the harness contract with dummy fields for each namespaced storage
2712
2723
  var_to_slot = storageExtension.write_harness_contract(tmp_file, harness_name, ns_storage)
2713
2724
  tmp_file.flush()
@@ -2720,13 +2731,6 @@ class CertoraBuildGenerator:
2720
2731
  build_dir / f"{Path(original_file).stem}_storage_extension.sol"
2721
2732
  )
2722
2733
 
2723
- # Add harness to compiler map
2724
- storageExtension.add_harness_to_compiler_map(
2725
- original_file,
2726
- tmp_file,
2727
- self.context
2728
- )
2729
-
2730
2734
  # normalize the path exactly the way collect_for_file expects it:
2731
2735
  abs_path = Util.abs_posix_path(tmp_file.name)
2732
2736
  self.context.file_to_contract[abs_path] = {harness_name}
@@ -2794,7 +2798,8 @@ class CertoraBuildGenerator:
2794
2798
  continue
2795
2799
 
2796
2800
  # Now that we have all the storage layout information, extract it once
2797
- slayouts[key] = self.extract_slayout(imported_file, ns_storage)
2801
+ slayouts[key] = self.extract_slayout(imported_file, ns_storage,
2802
+ get_relevant_compiler(Path(target_file), self.context))
2798
2803
 
2799
2804
  if self.context.test == str(Util.TestValue.STORAGE_EXTENSION_LAYOUT):
2800
2805
  raise Util.TestResultsReady(slayouts)
@@ -3575,7 +3580,11 @@ class CertoraBuildGenerator:
3575
3580
  return sources
3576
3581
 
3577
3582
  def __del__(self) -> None:
3578
- self.cleanup()
3583
+ try:
3584
+ self.cleanup()
3585
+ except ImportError:
3586
+ # Avoiding Python interpreter shutdown exceptions which are safe to ignore
3587
+ pass
3579
3588
 
3580
3589
 
3581
3590
  # make sure each source file exists and its path is in absolute format
@@ -3614,7 +3623,7 @@ def build_source_tree(sources: Set[Path], context: CertoraContext, overwrite: bo
3614
3623
 
3615
3624
  try:
3616
3625
  if overwrite:
3617
- # expecting target path to exist.
3626
+ # expecting the target path to exist.
3618
3627
  if target_path.exists():
3619
3628
  build_logger.debug(f"Overwriting {target_path} by copying from {source_path}")
3620
3629
  else:
@@ -3632,7 +3641,7 @@ def build_source_tree(sources: Set[Path], context: CertoraContext, overwrite: bo
3632
3641
  cwd_file_path.parent.mkdir(parents=True, exist_ok=True)
3633
3642
  cwd_file_path.touch()
3634
3643
 
3635
- # the empty file .project_directory is written in the source tree to denote the projecct directory
3644
+ # the empty file .project_directory is written in the source tree to denote the project directory
3636
3645
  rust_proj_dir = getattr(context, 'rust_project_directory', None)
3637
3646
  if rust_proj_dir:
3638
3647
  proj_dir_parent_relative = os.path.relpath(rust_proj_dir, os.getcwd())
@@ -3683,13 +3692,14 @@ def build_from_scratch(context: CertoraContext,
3683
3692
 
3684
3693
  # add to cache also source files that were found in the SDCs (e.g., storage extensions)
3685
3694
  paths_set = sdc.all_contract_files
3686
- for p in context.files:
3687
- paths_set.add(Path(p).absolute())
3695
+ for f in context.files:
3696
+ path = f.split(':')[0] # `f` is either 'path/to/file.sol' or 'path/to/file.sol:ContractName'
3697
+ paths_set.add(Path(path).absolute())
3688
3698
 
3689
3699
  # the contract files in SDCs are relative to .certora_sources. Which isn't good for us here.
3690
3700
  # Need to be relative to original paths
3691
3701
  for f in paths_set:
3692
- if is_relative_to(f, absolute_sources_dir):
3702
+ if f.is_relative_to(absolute_sources_dir):
3693
3703
  rel_f = f.relative_to(absolute_sources_dir)
3694
3704
  else:
3695
3705
  # may be an absolute path already outside .certora_sources, so we can keep it.
@@ -3724,8 +3734,7 @@ def build_from_scratch(context: CertoraContext,
3724
3734
 
3725
3735
  def build_from_cache_or_scratch(context: CertoraContext,
3726
3736
  certora_build_generator: CertoraBuildGenerator,
3727
- certora_verify_generator: CertoraVerifyGenerator,
3728
- certora_build_cache_manager: CertoraBuildCacheManager) \
3737
+ certora_verify_generator: CertoraVerifyGenerator) \
3729
3738
  -> Tuple[bool, bool, CachedFiles]:
3730
3739
  """
3731
3740
  Builds either from cache (fast path) or from scratch (slow path)
@@ -3742,10 +3751,10 @@ def build_from_cache_or_scratch(context: CertoraContext,
3742
3751
  False)
3743
3752
  return cache_hit, False, cached_files
3744
3753
 
3745
- build_cache_applicable = certora_build_cache_manager.cache_is_applicable(context)
3754
+ build_cache_applicable = CertoraBuildCacheManager.cache_is_applicable(context)
3746
3755
 
3747
3756
  if not build_cache_applicable:
3748
- build_cache_disabling_options = certora_build_cache_manager.cache_disabling_options(context)
3757
+ build_cache_disabling_options = CertoraBuildCacheManager.cache_disabling_options(context)
3749
3758
  build_logger.warning("Requested to enable the build cache, but the build cache is not applicable "
3750
3759
  f"to this run because of the given options: {build_cache_disabling_options}")
3751
3760
  cached_files = build_from_scratch(context, certora_build_generator,
@@ -3753,7 +3762,7 @@ def build_from_cache_or_scratch(context: CertoraContext,
3753
3762
  False)
3754
3763
  return cache_hit, False, cached_files
3755
3764
 
3756
- cached_files = certora_build_cache_manager.build_from_cache(context)
3765
+ cached_files = CertoraBuildCacheManager.build_from_cache(context)
3757
3766
  # if no match, will rebuild from scratch
3758
3767
  if cached_files is not None:
3759
3768
  # write to .certora_build.json
@@ -3792,7 +3801,7 @@ def build(context: CertoraContext, ignore_spec_syntax_check: bool = False) -> No
3792
3801
 
3793
3802
  try:
3794
3803
  input_config = InputConfig(context)
3795
-
3804
+ context.main_cache_key = CertoraBuildCacheManager.get_main_cache_key(context)
3796
3805
  # Create generators
3797
3806
  certora_build_generator = CertoraBuildGenerator(input_config, context)
3798
3807
 
@@ -3808,12 +3817,9 @@ def build(context: CertoraContext, ignore_spec_syntax_check: bool = False) -> No
3808
3817
  else:
3809
3818
  Ctx.run_local_spec_check(False, context)
3810
3819
 
3811
- certora_build_cache_manager = CertoraBuildCacheManager()
3812
-
3813
3820
  cache_hit, build_cache_enabled, cached_files = build_from_cache_or_scratch(context,
3814
3821
  certora_build_generator,
3815
- certora_verify_generator,
3816
- certora_build_cache_manager)
3822
+ certora_verify_generator)
3817
3823
 
3818
3824
  # avoid running the same test over and over again for each split run, context.split_rules is true only for
3819
3825
  # the first run and is set to [] for split runs
@@ -3833,7 +3839,7 @@ def build(context: CertoraContext, ignore_spec_syntax_check: bool = False) -> No
3833
3839
 
3834
3840
  # save in build cache
3835
3841
  if not cache_hit and build_cache_enabled and cached_files.may_store_in_build_cache:
3836
- certora_build_cache_manager.save_build_cache(context, cached_files)
3842
+ CertoraBuildCacheManager.save_build_cache(context, cached_files)
3837
3843
 
3838
3844
  certora_verify_generator.update_certora_verify_struct(True)
3839
3845
  certora_verify_generator.dump() # second dump with properly rooted specs
@@ -66,10 +66,9 @@ class CertoraBuildCacheManager:
66
66
  @returns None if no cache hit, otherwise - the matching `.certora_build.json` file, and a set of source files
67
67
  """
68
68
  build_cache_dir = Util.get_certora_build_cache_dir()
69
- main_cache_key = CertoraBuildCacheManager.get_main_cache_key(context)
70
- main_cache_entry_dir = build_cache_dir / main_cache_key
69
+ main_cache_entry_dir = build_cache_dir / context.main_cache_key
71
70
  if not main_cache_entry_dir.exists():
72
- build_cache_logger.info(f"cache miss on build cache key {main_cache_key}")
71
+ build_cache_logger.info(f"cache miss on build cache key {context.main_cache_key}")
73
72
  return None
74
73
 
75
74
  # here's the tricky matching part:
@@ -92,7 +91,7 @@ class CertoraBuildCacheManager:
92
91
  build_cache_logger.debug(f"Current sub build cache key computed for {file_list_file} is invalid")
93
92
  continue
94
93
  elif sub_cache_key_current_for_list == sub_cache_key_from_saved_entry:
95
- build_cache_logger.info(f"We have a match on build cache key {main_cache_key} and "
94
+ build_cache_logger.info(f"We have a match on build cache key {context.main_cache_key} and "
96
95
  f"{sub_cache_key_current_for_list}")
97
96
  sub_cache_key = sub_cache_key_current_for_list
98
97
  all_contract_files = set([Path(f) for f in file_list])
@@ -103,24 +102,24 @@ class CertoraBuildCacheManager:
103
102
 
104
103
  if sub_cache_key is None:
105
104
  build_cache_logger.info("All sub-cache-key file list files missed, cache miss on build cache key "
106
- f"{main_cache_key}")
105
+ f"{context.main_cache_key}")
107
106
  return None
108
107
 
109
108
  # cache hit
110
109
  certora_build_file = main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.certora_build_suffix}"
111
110
  if not certora_build_file.exists():
112
- build_cache_logger.warning(f"Got a cache-hit on build cache key {main_cache_key} and {sub_cache_key} "
111
+ build_cache_logger.warning(f"Got a cache-hit on build cache key {context.main_cache_key} and {sub_cache_key} "
113
112
  "but .certora_build.json file does not exist")
114
113
  return None
115
114
 
116
115
  if all_contract_files is None: # should not be feasible
117
- build_cache_logger.warning(f"Got a cache-hit on build cache key {main_cache_key} and {sub_cache_key} "
118
- "but file list file does not exist")
116
+ build_cache_logger.warning(f"Got a cache-hit on build cache key {context.main_cache_key} and "
117
+ f"{sub_cache_key} but file list file does not exist")
119
118
  return None
120
119
 
121
120
  build_output_props_file = main_cache_entry_dir / f"{sub_cache_key}.{CachedFiles.build_output_props_suffix}"
122
121
  if not build_output_props_file.exists():
123
- build_cache_logger.warning(f"Got a cache-hit on build cache key {main_cache_key} and {sub_cache_key} "
122
+ build_cache_logger.warning(f"Got a cache-hit on build cache key {context.main_cache_key} and {sub_cache_key} "
124
123
  f"but {CachedFiles.build_output_props_suffix} file does not exist")
125
124
  return None
126
125
 
@@ -131,26 +130,26 @@ class CertoraBuildCacheManager:
131
130
  @staticmethod
132
131
  def save_build_cache(context: CertoraContext, cached_files: CachedFiles) -> None:
133
132
  build_cache_dir = Util.get_certora_build_cache_dir()
134
- main_cache_key = CertoraBuildCacheManager.get_main_cache_key(context)
135
- main_cache_entry_dir = build_cache_dir / main_cache_key
133
+ main_cache_entry_dir = build_cache_dir / context.main_cache_key
136
134
  sub_cache_key = CertoraBuildCacheManager.get_sub_cache_key(cached_files.all_contract_files)
137
135
  if sub_cache_key is None:
138
- build_cache_logger.warning(f"Cannot save cache for main build cache key {main_cache_key} "
136
+ build_cache_logger.warning(f"Cannot save cache for main build cache key {context.main_cache_key} "
139
137
  "as sub-cache-key could not be computed")
140
138
  return
141
139
 
142
140
  if main_cache_entry_dir.exists():
143
- build_cache_logger.info(f"main build cache key already exists {main_cache_key}, "
141
+ build_cache_logger.info(f"main build cache key already exists {context.main_cache_key}, "
144
142
  f"saving sub build cache key {sub_cache_key}")
145
143
  if cached_files.all_exist(main_cache_entry_dir, sub_cache_key):
146
144
  build_cache_logger.debug("cache already saved under this build cache key, override")
147
145
  else:
148
- build_cache_logger.debug(f"cache was corrupted, need to re-save build cache key {main_cache_key} "
149
- f"and sub cache key {sub_cache_key}")
146
+ build_cache_logger.debug(f"cache was corrupted, need to re-save build cache key "
147
+ f"{context.main_cache_key} and sub cache key {sub_cache_key}")
150
148
  CertoraBuildCacheManager.save_files(cached_files, main_cache_entry_dir,
151
149
  sub_cache_key)
152
150
  else:
153
- build_cache_logger.info(f"saving main build cache key {main_cache_key} and sub cache key {sub_cache_key}")
151
+ build_cache_logger.info(f"saving main build cache key {context.main_cache_key} and sub cache key "
152
+ f"{sub_cache_key}")
154
153
  safe_create_dir(main_cache_entry_dir)
155
154
  CertoraBuildCacheManager.save_files(cached_files, main_cache_entry_dir,
156
155
  sub_cache_key)
@@ -180,6 +179,8 @@ class CertoraBuildCacheManager:
180
179
  trg = trg_path_with_additional_included_files / post_autofinder_dir.name
181
180
  if post_autofinder_dir != trg:
182
181
  if post_autofinder_dir.is_dir():
182
+ if trg.exists():
183
+ shutil.rmtree(trg)
183
184
  Util.safe_copy_folder(post_autofinder_dir, trg, shutil.ignore_patterns())
184
185
  else:
185
186
  # highly unlikely .post_autofinder.[digit] will be a file and not a directory,
@@ -13,10 +13,20 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
 
16
+ from __future__ import annotations
17
+
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ scripts_dir_path = Path(__file__).parent.parent.resolve() # containing directory
22
+ sys.path.insert(0, str(scripts_dir_path))
23
+
16
24
  import glob
17
25
  import shutil
26
+ import time
27
+ import logging
18
28
  from pathlib import Path
19
- from typing import Set
29
+ from typing import Set, Dict
20
30
 
21
31
  from CertoraProver.certoraBuild import build_source_tree
22
32
  from CertoraProver.certoraContextClass import CertoraContext
@@ -25,6 +35,25 @@ import CertoraProver.certoraContextAttributes as Attrs
25
35
  from Shared import certoraUtils as Util
26
36
 
27
37
 
38
+ log = logging.getLogger(__name__)
39
+
40
+
41
+ def build_rust_project(context: CertoraContext, timings: Dict) -> None:
42
+ """
43
+ Compile the Rust artefact and record elapsed time in *timings*.
44
+
45
+ Args:
46
+ context: The CertoraContext object containing the configuration.
47
+ timings: A dictionary to store timing information.
48
+ """
49
+ log.debug("Build Rust target")
50
+ start = time.perf_counter()
51
+ set_rust_build_directory(context)
52
+ timings["buildTime"] = round(time.perf_counter() - start, 4)
53
+ if context.test == str(Util.TestValue.AFTER_BUILD):
54
+ raise Util.TestResultsReady(context)
55
+
56
+
28
57
  def set_rust_build_directory(context: CertoraContext) -> None:
29
58
  if not context.files:
30
59
  build_rust_app(context)
@@ -41,6 +70,7 @@ def set_rust_build_directory(context: CertoraContext) -> None:
41
70
  except Exception as e:
42
71
  raise Util.CertoraUserInputError(f"Collecting build files failed with the exception: {e}")
43
72
 
73
+
44
74
  def build_rust_app(context: CertoraContext) -> None:
45
75
  assert not context.files, "build_rust_app: expecting files to be empty"
46
76
  if context.build_script:
@@ -51,6 +81,7 @@ def build_rust_app(context: CertoraContext) -> None:
51
81
  feature_flag = '--features'
52
82
  if context.cargo_tools_version:
53
83
  build_command.extend(["--tools-version", context.cargo_tools_version])
84
+ context.rust_project_directory = Util.find_nearest_cargo_toml()
54
85
 
55
86
  if context.cargo_features is not None:
56
87
  build_command.append(feature_flag)
@@ -61,24 +92,6 @@ def build_rust_app(context: CertoraContext) -> None:
61
92
 
62
93
  run_rust_build(context, build_command)
63
94
 
64
- def add_solana_files_from_prover_args(context: CertoraContext) -> None:
65
- if context.prover_args:
66
- inlining_file = False
67
- summaries_file = False
68
- for prover_arg in context.prover_args:
69
- for arg in prover_arg.split(' '):
70
- if inlining_file:
71
- context.solana_inlining = context.solana_inlining or [Path(arg)]
72
- inlining_file = False
73
- if summaries_file:
74
- context.solana_summaries = context.solana_summaries or [Path(arg)]
75
- summaries_file = False
76
-
77
- if arg == '-solanaInlining':
78
- inlining_file = True
79
- elif arg == '-solanaSummaries':
80
- summaries_file = True
81
-
82
95
 
83
96
  def add_solana_files_to_sources(context: CertoraContext, sources: Set[Path]) -> None:
84
97
  for attr in [Attrs.SolanaProverAttributes.SOLANA_INLINING,
@@ -102,7 +115,7 @@ def add_solana_files_to_sources(context: CertoraContext, sources: Set[Path]) ->
102
115
 
103
116
 
104
117
  def collect_files_from_rust_sources(context: CertoraContext, sources: Set[Path]) -> None:
105
- patterns = ["*.rs", "*.so", "*.wasm", "Cargo.toml", "Cargo.lock", "justfile"]
118
+ patterns = ["*.rs", "*.so", "*.wasm", Util.CARGO_TOML_FILE, "Cargo.lock", "justfile"]
106
119
  exclude_dirs = [".certora_internal"]
107
120
 
108
121
  if hasattr(context, 'rust_project_directory'):
@@ -125,7 +138,6 @@ def collect_files_from_rust_sources(context: CertoraContext, sources: Set[Path])
125
138
  if getattr(context, 'conf_file', None) and Path(context.conf_file).exists():
126
139
  sources.add(Path(context.conf_file).absolute())
127
140
 
128
- add_solana_files_from_prover_args(context)
129
141
  add_solana_files_to_sources(context, sources)
130
142
 
131
143
 
@@ -13,13 +13,6 @@
13
13
  # You should have received a copy of the GNU General Public License
14
14
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
15
 
16
- """
17
- Shared helpers for Rust-based targets (Solana & Soroban).
18
-
19
- Placing the build logic in one module removes
20
- duplication from the dedicated entry scripts.
21
- """
22
-
23
16
  from __future__ import annotations
24
17
 
25
18
  import sys
@@ -28,25 +21,21 @@ from pathlib import Path
28
21
  scripts_dir_path = Path(__file__).parent.parent.resolve() # containing directory
29
22
  sys.path.insert(0, str(scripts_dir_path))
30
23
 
24
+ import shutil
31
25
  import time
32
26
  import logging
33
- from typing import Dict
34
-
35
- from Shared import certoraUtils as Util
27
+ from pathlib import Path
28
+ from typing import Set, Dict
36
29
 
30
+ from CertoraProver.certoraBuild import build_source_tree
37
31
  from CertoraProver.certoraContextClass import CertoraContext
38
-
39
- from CertoraProver.certoraBuildRust import set_rust_build_directory
32
+ from Shared import certoraUtils as Util
40
33
 
41
34
 
42
35
  log = logging.getLogger(__name__)
43
36
 
44
37
 
45
- # --------------------------------------------------------------------------- #
46
- # Build
47
- # --------------------------------------------------------------------------- #
48
-
49
- def build_rust_project(context: CertoraContext, timings: Dict) -> None:
38
+ def build_sui_project(context: CertoraContext, timings: Dict) -> None:
50
39
  """
51
40
  Compile the Rust artefact and record elapsed time in *timings*.
52
41
 
@@ -56,7 +45,24 @@ def build_rust_project(context: CertoraContext, timings: Dict) -> None:
56
45
  """
57
46
  log.debug("Build Rust target")
58
47
  start = time.perf_counter()
59
- set_rust_build_directory(context)
48
+ set_sui_build_directory(context)
60
49
  timings["buildTime"] = round(time.perf_counter() - start, 4)
61
50
  if context.test == str(Util.TestValue.AFTER_BUILD):
62
51
  raise Util.TestResultsReady(context)
52
+
53
+
54
+ def set_sui_build_directory(context: CertoraContext) -> None:
55
+ assert context.move_path, "build_sui_project: expecting move_path to link to a build directory"
56
+
57
+ shutil.copytree(context.move_path, Util.get_build_dir() / Path(context.move_path).name)
58
+
59
+ sources: Set[Path] = set()
60
+ if getattr(context, 'conf_file', None) and Path(context.conf_file).exists():
61
+ sources.add(Path(context.conf_file).absolute())
62
+
63
+ try:
64
+ # Create generators
65
+ build_source_tree(sources, context)
66
+
67
+ except Exception as e:
68
+ raise Util.CertoraUserInputError(f"Collecting build files failed with the exception: {e}")