Skip to content

Commit

Permalink
Merge branch 'reconstruct_function_tags' of github.com:costa-group/gr…
Browse files Browse the repository at this point in the history
…ey into reconstruct_function_tags
  • Loading branch information
alexcere committed Feb 26, 2025
2 parents 44000b2 + d4d72fa commit 231de63
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 13 deletions.
28 changes: 28 additions & 0 deletions scripts/compare_outputs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import json
from jsondiff import diff

def compare_files(json_file1, json_file2):
with open(json_file1, 'r') as f:
json1 = json.load(f)

with open(json_file2, 'r') as f:
json2 = json.load(f)

if json1.keys() != json2.keys():
print("JSONS have different contract fields")
return False

# Drop keys for gas
for key, json1_answers in json1.items():
json2_answers = json2[key]

for answer in [*json1_answers, *json2_answers]:
answer.pop("gasUsed")
answer.pop("gasUsedForDeposit")

answer = diff(json1, json2)
print("FINAL", answer)
return answer

if __name__ == "__main__":
pass
24 changes: 16 additions & 8 deletions scripts/experiments_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sys
import pandas as pd
from count_num_ins import instrs_from_opcodes
from compare_outputs import compare_files


def combine_dfs(csv_folder: Path, combined_csv: Path):
Expand Down Expand Up @@ -72,25 +73,31 @@ def execute_yul_test(yul_file: str, csv_folder: Path) -> None:
print(" ".join(replace_command))

testrunner_command_original = [
"/experiments/Systems/solidity/build/test/tools/testrunner",
"/experiments/Systems/evmone/build/lib/libevmone.so.0.13.0",
"/system/experiments/Systems/solidity/build/test/tools/testrunner",
"/system/experiments/Systems/evmone_ahernandez/build/lib/libevmone.so",
test_file,
os.path.join(yul_dir, "resultOriginal.json"),
]
subprocess.run(testrunner_command_original)

testrunner_command_grey = [
"/experiments/Systems/solidity/build/test/tools/testrunner",
"/experiments/Systems/evmone/build/lib/libevmone.so.0.13.0",
f"{yul_dir}/test",
"/system/experiments/Systems/solidity/build/test/tools/testrunner",
"/system/experiments/Systems/evmone_ahernandez/build/lib/libevmone.so",
f"{yul_dir}/test_grey",
os.path.join(yul_dir, "resultGrey.json"),
]
# print(' '.join(testrunner_command_grey))
subprocess.run(testrunner_command_grey)

# Compare results
result_original = os.path.join(yul_dir, "resultOriginal.json")
result_grey = os.path.join(yul_dir, "resultGrey.json")
if filecmp.cmp(result_original, result_grey, shallow=False):

# We need to compare them dropping the gas usage
file_comparison = compare_files(result_original, result_grey)

# If file_comparison is empty, it means that the match is precise
if len(file_comparison) == 0:
print("[RES]: Test passed.")
result_dict = instrs_from_opcodes(output_file, log_file)
csv_file = csv_folder.joinpath("correctos").joinpath(csv_name)
Expand All @@ -109,8 +116,9 @@ def run_experiments(n_cpus):
# Change the directory to the root

os.chdir("..")
DIRECTORIO_TESTS = "examples/test/semanticTests"
# DIRECTORIO_TESTS = "examples/test/semanticTests"
# DIRECTORIO_TESTS = "tests_evmone"
DIRECTORIO_TESTS = "falla_test/"
CSV_FOLDER = Path("csvs")
CSV_FOLDER.mkdir(exist_ok=True, parents=True)
CSV_FOLDER.joinpath("correctos").mkdir(exist_ok=True, parents=True)
Expand All @@ -127,7 +135,7 @@ def run_experiments(n_cpus):
with mp.Pool(n_cpus) as p:
p.starmap(execute_yul_test, [[file, CSV_FOLDER] for file in yul_files])
print("Procesamiento completado.")
combine_dfs(CSV_FOLDER, Path("combined.csv"))
# combine_dfs(CSV_FOLDER, Path("combined.csv"))


if __name__ == "__main__":
Expand Down
12 changes: 8 additions & 4 deletions src/execution/main_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from parser.parser import parse_CFG_from_json_dict
from parser.cfg import CFG
from execution.sol_compilation import SolidityCompilation
from solution_generation.reconstruct_bytecode import asm_from_cfg, store_asm_output, store_binary_output
from solution_generation.reconstruct_bytecode import asm_from_cfg, store_asm_output, store_binary_output, store_asm_standard_json_output
from greedy.ids_from_spec import cfg_spec_ids
from liveness.layout_generation import layout_generation
from cfg_methods.preprocessing_methods import preprocess_cfg
Expand Down Expand Up @@ -114,7 +114,11 @@ def main(args):

assembly_path = store_asm_output(asm_contract, cfg_name, cfg_dir)

synt_binary = SolidityCompilation.importer_assembly_file(assembly_path, solc_executable=args.solc_executable)
print("Contract: " + cfg_name + " -> EVM Code: " + synt_binary)
std_assembly_path = store_asm_standard_json_output(asm_contract, cfg_name, cfg_dir)

#synt_binary = SolidityCompilation.importer_assembly_file(assembly_path, solc_executable=args.solc_executable)
synt_binary_stdjson = SolidityCompilation.importer_assembly_standard_json_file(std_assembly_path, deployed_contract = cfg_name, solc_executable = args.solc_executable)

print("Contract: " + cfg_name + " -> EVM Code: " + synt_binary_stdjson)

store_binary_output(cfg_name, synt_binary, cfg_dir)
store_binary_output(cfg_name, synt_binary_stdjson, cfg_dir)
26 changes: 25 additions & 1 deletion src/execution/sol_compilation.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,22 @@ def process_importer_output(sol_output: str, deployed_contract: Optional[str], s
contract_header = r"Binary:\n(.*?)\n"
return re.search(contract_header, sol_output).group(1)

def process_importer_standard_output(sol_output: str, deployed_contract: Optional[str], selected_header: str) -> str:
"""
Given the compiler output from solc after the importer standard-json option, extracts the information
of the corresponding contract (binary)
"""

json_output = json.loads(sol_output)

contracts = json_output["contracts"]
assert deployed_contract in contracts, f"Contract {deployed_contract} not deployed"

deployed_contract_info = contracts[deployed_contract][""]

return deployed_contract_info["evm"]["bytecode"]["object"]



class SolidityCompilation:
"""
Expand All @@ -239,7 +255,7 @@ def __init__(self, final_file: Optional[str], solc_command: str):
self._solc_command: str = solc_command

# TODO: decide how to represent via-ir
self._via_ir = False
self._via_ir = True
self._yul_setting = False

# Function to select the information from the contract
Expand All @@ -264,6 +280,14 @@ def importer_assembly_file(json_file: str, deployed_contract: Optional[str] = No
compilation.process_output_function = process_importer_output
return compilation.compile_single_sol_file(json_file, deployed_contract, "bin")

@staticmethod
def importer_assembly_standard_json_file(json_file: str, deployed_contract: Optional[str] = None,
final_file: Optional[str] = None, solc_executable: str = "solc"):
compilation = SolidityCompilation(final_file, solc_executable)
compilation.flags = "--standard-json"
compilation.process_output_function = process_importer_standard_output
return compilation.compile_single_sol_file(json_file, deployed_contract, "bin")

@staticmethod
def from_multi_sol(multi_sol_info: Dict[str, Any], deployed_contract: str,
final_file: Optional[str] = None, solc_executable: str = "solc") -> Optional[Dict[str, Yul_CFG_T]]:
Expand Down
47 changes: 47 additions & 0 deletions src/solution_generation/reconstruct_bytecode.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,55 @@ def store_asm_output(json_object: Dict[str, Any], object_name: str, cfg_dir: Pat
json.dump(json_object, f, indent=4)
return file_to_store

def store_asm_standard_json_output(json_object: Dict[str, Any], object_name: str, cfg_dir: Path) -> Path:
file_to_store = cfg_dir.joinpath(object_name + "_standard_json_output.json")
output_file = build_standard_json_output(json_object, object_name)
with open(file_to_store, 'w') as f:
json.dump(output_file, f, indent=4)
return file_to_store

def store_binary_output(object_name: str, evm_code: str, cfg_dir: Path) -> None:
file_to_store = cfg_dir.joinpath(object_name + "_bin.evm")
with open(file_to_store, 'w') as f:
f.write(evm_code)


def build_standard_json_output(json_object: Dict[str, Any], object_name : str) -> Dict[str,Any]:
output = {}

output["language"] = "EVMAssembly"
build_standard_json_settings(output)

output["sources"] = {}
output["sources"][object_name] = {}
output["sources"][object_name]["assemblyJson"] = json_object


return output

def build_standard_json_settings(output_json):
output_json["settings"] = {}

output = build_output_selection()
output_json["settings"]["outputSelection"] = output

opt_config = build_optimizer_configuration()
output_json["settings"]["optimizer"] = opt_config

output_json["settings"]["viaIR"] = True
output_json["settings"]["metadata"] = {}
output_json["settings"]["metadata"]["appendCBOR"] = False

def build_output_selection():
output_selection = {}
output_selection["*"] = {}
output_selection["*"][""] = ["*"]

return output_selection

def build_optimizer_configuration():
config = {}
config["enabled"] = True
config["runs"] = 200

return config

0 comments on commit 231de63

Please sign in to comment.