示例#1
0
    def run(self, path):
        fd, output_exec_path = tempfile.mkstemp(prefix="hs-exec")
        os.fdopen(fd).close()
        try:
            ghc_proc, get_stats = Process.popen_with_timing(
                [
                    self.ghc_bin,
                    path,
                    "-O3",
                    "-o",
                    output_exec_path,
                ],
                stdout=subprocess.DEVNULL)
            exitcode = ghc_proc.wait()
            assert exitcode == 0, f"ghc failed with exitcode {exitcode}"
            compile_stats = get_stats()

            exec_proc, get_stats = Process.popen_with_timing(
                [
                    output_exec_path,
                ], stdout=subprocess.DEVNULL)
            exitcode = exec_proc.wait()
            assert exitcode == 0, f"ghc compiled binary failed with exitcode {exitcode}"

            return {
                "ghc_real_time": compile_stats["real_time"],
                "ghc_max_mem": compile_stats["max_mem"],
                **get_stats(),
            }
        finally:
            os.remove(output_exec_path)
示例#2
0
    def run_vmtest(self, json_path):
        _, test_type = load_and_check_test_format(json_path)

        assert test_type != TestType.STATE, "kevm does not support the state test format"

        # run json to kore script
        proc = Process.popen_with_log([
            "python",
            self.json_to_kore_script,
            json_path,
            self.get_schedule_kast(),
            self.get_mode_kast("NORMAL" if test_type ==
                               TestType.BLOCKCHAIN else "VMTESTS"),
            str(self.chain_id),
        ],
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)

        input_kore_source = proc.stdout.read()
        stderr = proc.stderr.read().decode()
        exitcode = proc.wait()
        if exitcode != 0:
            raise Exception(
                f"json-to-kore script {self.json_to_kore_script} returned non-zero exitcode {exitcode} and stderr:\n{stderr}"
            )

        # run interpreter in the llvm_k_directory to get output state
        with tempfile.NamedTemporaryFile() as input_kore_file:
            # with tempfile.NamedTemporaryFile() as output_kore_file:
            input_kore_file.write(input_kore_source)
            input_kore_file.flush()

            proc, get_stats = Process.popen_with_timing(
                [
                    self.llvm_k_interpreter,
                    input_kore_file.name,
                    "-1",
                    "/dev/null",  # output_kore_file.name,
                ],
                stderr=subprocess.DEVNULL,
                stdout=subprocess.DEVNULL)

            # print(proc.stdout.read())
            # print(proc.stderr.read())

            exitcode = proc.wait()
            # print(open(output_kore_file.name).read())
            if exitcode != 0:
                raise Exception(
                    f"interpreter {self.llvm_k_interpreter} returned non-zero exitcode {exitcode}"
                )

            return get_stats()
示例#3
0
    def run_vmtest(self, json_path):
        _, test_type = load_and_check_test_format(json_path)

        assert test_type in [
            TestType.BLOCKCHAIN, TestType.VM
        ], "ethereum js does not support this type of test"

        cwd = os.getcwd()
        absolute_json_path = os.path.realpath(json_path)

        try:
            os.chdir(self.script_dir)

            proc, get_stats = Process.popen_with_timing(
                [
                    "npx",
                    "ts-node",
                    "index.ts"
                    if test_type == TestType.BLOCKCHAIN else "vm.ts",
                    absolute_json_path,
                ],
                stderr=subprocess.DEVNULL)

            exitcode = proc.wait()
        finally:
            os.chdir(cwd)

        if exitcode != 0:
            raise Exception(
                f"ethereum js script {self.script_dir}/index.ts returned non-zero exitcode {exitcode}"
            )

        return get_stats()
示例#4
0
    def run_vmtest(self, json_path):
        _, test_type = load_and_check_test_format(json_path)

        assert test_type in [TestType.STATE, TestType.VM
                             ], "py-evm does not support this type of test"

        proc, get_stats = Process.popen_with_timing([
            "python3",
            self.script,
            json_path,
        ],
                                                    stderr=subprocess.DEVNULL)

        exitcode = proc.wait()
        if exitcode != 0:
            raise Exception(
                f"py-evm script {self.script} returned non-zero exitcode {exitcode}"
            )

        return get_stats()
示例#5
0
    def run_vmtest(self, json_path):
        _, test_type = load_and_check_test_format(json_path)

        assert test_type != TestType.BLOCKCHAIN, "openethereum does not support full blockchain tests"

        proc, get_stats = Process.popen_with_timing([
            self.evm_binary,
            "stats-jsontests-vm" if test_type == TestType.VM else "state-test",
            json_path,
        ],
                                                    stderr=subprocess.DEVNULL,
                                                    stdout=subprocess.DEVNULL)

        exitcode = proc.wait()
        if exitcode != 0:
            raise Exception(
                f"openethereum evmbin {self.evm_binary} returned non-zero exitcode {exitcode}"
            )

        return get_stats()
示例#6
0
    def kast_pgm(self, path, input_file_path):
        kompiled_dir, _ = self.get_kompiled_dir(path)

        pgm_kore_path = os.path.join(kompiled_dir, "pgm.kore")
        if os.path.isfile(pgm_kore_path) and not self.is_newer_than(
                path, pgm_kore_path):
            print(ANSI.COLOR_GREY + "+ kore program is up-to-date" +
                  ANSI.RESET)
            return pgm_kore_path

        try:
            with open(pgm_kore_path, "wb") as output_kore_file:
                kast_proc, _ = Process.popen_with_timing(
                    [
                        *self.gen_k_command("kast"),
                        "--input",
                        "program",
                        "--output",
                        "kore",
                        "--directory",
                        kompiled_dir,
                        input_file_path,
                    ],
                    stdout=subprocess.PIPE,
                    env=self.k_env)

                output_kore_file.write(KTestRunner.PGM_PREFIX.encode())
                output_kore_file.write(kast_proc.stdout.read())
                output_kore_file.write(KTestRunner.PGM_SUFFIX.encode())
                output_kore_file.flush()

                exitcode = kast_proc.wait(timeout=self.timeout)
                assert exitcode == 0, f"kast failed with exitcode {exitcode}"
        except KeyboardInterrupt as e:
            os.remove(pgm_kore_path)
            raise e
        except Exception as e:
            os.remove(pgm_kore_path)
            raise e

        return pgm_kore_path
示例#7
0
    def eval_one_term(self, path, input_file_path):
        _, actual_kompiled_dir = self.get_kompiled_dir(path)

        pgm_kore_path = self.kast_pgm(path, input_file_path)

        # run interpreter
        interpreter_proc, get_stats = Process.popen_with_timing([
            os.path.join(actual_kompiled_dir, "interpreter"),
            pgm_kore_path,
            "-1",
            "/dev/null",
        ])
        exitcode = interpreter_proc.wait(timeout=self.timeout)
        assert exitcode == 0, f"interpreter failed with exitcode {exitcode}"

        # return {
        #     "kast_real_time": kast_stats["real_time"],
        #     "kast_max_mem": kast_stats["max_mem"],
        #     **get_stats(),
        # }
        return get_stats()
示例#8
0
    def kompile_definition(self, path):
        kompiled_dir, actual_kompiled_dir = self.get_kompiled_dir(path)

        # if the kompiled directory is up to date, no need to re-kompile
        timestamp = os.path.join(actual_kompiled_dir, "timestamp")
        if os.path.isfile(timestamp) and not self.is_newer_than(
                path, timestamp):
            print(ANSI.COLOR_GREY + "+ kompiled directory is up-to-date" +
                  ANSI.RESET)
            return

        proc, _ = Process.popen_with_timing([
            *self.gen_k_command("kompile"),
            path,
            "-Wno",
            "unused-var",
            "-O3",
            "--directory",
            kompiled_dir,
        ],
                                            env=self.k_env)
        exitcode = proc.wait(timeout=self.timeout)
        assert exitcode == 0, f"kompile failed with exitcode {exitcode}"
示例#9
0
 def run(self, path):
     maude_proc, get_stats = Process.popen_with_timing(
         [self.maude_binary, path], stdout=subprocess.DEVNULL)
     exitcode = maude_proc.wait()
     assert exitcode == 0, f"maude failed with exitcode {exitcode}"
     return get_stats()
示例#10
0
    def run_vmtest(self, json_path):
        # geth evm doesn't natively support the vmtest format
        # (https://ethdocs.org/en/latest/contracts-and-transactions/ethereum-tests/vm_tests/)
        # so we are manually setting up the account info and transaction info etc.

        test_config, test_type = load_and_check_test_format(json_path)

        # a VERY coarse approximation right now
        # only set the code and input data

        assert test_type != TestType.BLOCKCHAIN, "geth does not support full blockchain tests"

        total_ops = 0
        total_gas = 0

        def process_trace(line):
            nonlocal total_ops
            nonlocal total_gas
            # if line.startswith(b"{\"pc\""):
            #     total_ops += 1
            #     print("\r" + str(total_ops), end="")
            # else:
            #     print(line)
            try:
                obj = json.loads(line)
                if "op" in obj:
                    total_ops += 1
                    # print("\r" + str(total_ops), end="")
                if "gasCost" in obj:
                    total_gas += int(obj["gasCost"], 16)
            except:
                pass

        if test_type == TestType.VM:
            with tempfile.NamedTemporaryFile() as code_file:
                with tempfile.NamedTemporaryFile() as data_file:
                    # note: this is an approximation of
                    # what the test actually describes
                    assert len(test_config) == 1
                    (_, test_config), = test_config.items()

                    code_file.write(test_config["exec"]["code"].encode())
                    code_file.flush()

                    data_file.write(test_config["exec"]["data"].encode())
                    data_file.flush()

                    proc, get_stats = Process.popen_with_timing(
                        [
                            self.evm_binary,
                            # "--json",
                            # "--nomemory",
                            # "--nostack",
                            "--codefile",
                            code_file.name,
                            "--inputfile",
                            data_file.name,
                            "run",
                        ],
                        stderr=subprocess.PIPE,
                        stdout=subprocess.DEVNULL)
                    while True:
                        line = proc.stderr.readline()
                        if line == b"": break
                        process_trace(line)
                    exitcode = proc.wait()
        else:
            # STATE or UNKNOWN test
            proc, get_stats = Process.popen_with_timing(
                [
                    self.evm_binary,
                    # "--json",
                    # "--nomemory",
                    # "--nostack",
                    "statetest",
                    json_path,
                ],
                stderr=subprocess.PIPE,
                stdout=subprocess.DEVNULL)
            while True:
                line = proc.stderr.readline()
                if line == b"": break
                process_trace(line)
            exitcode = proc.wait()

        if exitcode != 0:
            raise Exception(
                f"geth evm {self.evm_binary} returned non-zero exitcode {exitcode}"
            )

        return {"total_ops": total_ops, "total_gas": total_gas, **get_stats()}