예제 #1
0
 def __init__(self):
     plot_seeds: List[bytes32] = [
         ProofOfSpace.calculate_plot_seed(pool_pk, plot_pk)
         for plot_pk in plot_pks
     ]
     self.plot_dir = os.path.join("tests", "plots")
     self.filenames: List[str] = [
         "genesis-plots-" + str(k) +
         sha256(int.to_bytes(i, 4, "big")).digest().hex() + ".dat"
         for i in range(num_plots)
     ]
     done_filenames = set()
     try:
         for pn, filename in enumerate(self.filenames):
             if not os.path.exists(os.path.join(self.plot_dir, filename)):
                 plotter = DiskPlotter()
                 plotter.create_plot_disk(
                     self.plot_dir,
                     self.plot_dir,
                     filename,
                     k,
                     b"genesis",
                     plot_seeds[pn],
                 )
                 done_filenames.add(filename)
     except KeyboardInterrupt:
         for filename in self.filenames:
             if filename not in done_filenames and os.path.exists(
                     os.path.join(self.plot_dir, filename)):
                 os.remove(os.path.join(self.plot_dir, filename))
         sys.exit(1)
예제 #2
0
    def _add_plot(
        self, str_path: str, plot_sk: PrivateKey, pool_pk: Optional[PublicKey]
    ) -> bool:
        plot_config = load_config(self.root_path, "plots.yaml")

        if pool_pk is None:
            for pool_pk_cand in self.pool_pubkeys:
                pr = DiskProver(str_path)
                if (
                    ProofOfSpace.calculate_plot_seed(
                        pool_pk_cand, plot_sk.get_public_key()
                    )
                    == pr.get_id()
                ):
                    pool_pk = pool_pk_cand
                    break
        if pool_pk is None:
            return False
        plot_config["plots"][str_path] = {
            "sk": bytes(plot_sk).hex(),
            "pool_pk": bytes(pool_pk).hex(),
        }
        save_config(self.root_path, "plots.yaml", plot_config)
        self._refresh_plots()
        return True
예제 #3
0
def main():
    """
    Script for checking all plots in the plots.yaml file. Specify a number of challenge to test for each plot.
    """

    parser = argparse.ArgumentParser(description="Chia plot checking script.")
    parser.add_argument("-n",
                        "--num",
                        help="Number of challenges",
                        type=int,
                        default=1000)
    args = parser.parse_args()

    v = Verifier()
    if os.path.isfile(plot_config_filename):
        plot_config = safe_load(open(plot_config_filename, "r"))
        for plot_filename, plot_info in plot_config["plots"].items():
            plot_seed: bytes32 = ProofOfSpace.calculate_plot_seed(
                PublicKey.from_bytes(bytes.fromhex(plot_info["pool_pk"])),
                PrivateKey.from_bytes(bytes.fromhex(
                    plot_info["sk"])).get_public_key(),
            )
            if not os.path.isfile(plot_filename):
                # Tries relative path
                full_path: str = os.path.join(plot_root, plot_filename)
                if not os.path.isfile(full_path):
                    # Tries absolute path
                    full_path: str = plot_filename
                    if not os.path.isfile(full_path):
                        print(f"Plot file {full_path} not found.")
                        continue
                pr = DiskProver(full_path)
            else:
                pr = DiskProver(plot_filename)

            total_proofs = 0
            try:
                for i in range(args.num):
                    challenge = sha256(i.to_bytes(32, "big")).digest()
                    for index, quality in enumerate(
                            pr.get_qualities_for_challenge(challenge)):
                        proof = pr.get_full_proof(challenge, index)
                        total_proofs += 1
                        ver_quality = v.validate_proof(plot_seed,
                                                       pr.get_size(),
                                                       challenge, proof)
                        assert quality == ver_quality
            except BaseException as e:
                print(
                    f"{type(e)}: {e} error in proving/verifying for plot {plot_filename}"
                )
            print(
                f"{plot_filename}: Proofs {total_proofs} / {args.num}, {round(total_proofs/float(args.num), 4)}"
            )
    else:
        print(f"Not plot file found at {plot_config_filename}")
예제 #4
0
def main():
    """
    Script for creating plots and adding them to the plot config file.
    """
    root_path = DEFAULT_ROOT_PATH
    plot_config_filename = config_path_for_filename(root_path, "plots.yaml")
    key_config_filename = config_path_for_filename(root_path, "keys.yaml")

    parser = argparse.ArgumentParser(description="Chia plotting script.")
    parser.add_argument("-k", "--size", help="Plot size", type=int, default=20)
    parser.add_argument("-n",
                        "--num_plots",
                        help="Number of plots",
                        type=int,
                        default=10)
    parser.add_argument("-i",
                        "--index",
                        help="First plot index",
                        type=int,
                        default=0)
    parser.add_argument("-p",
                        "--pool_pub_key",
                        help="Hex public key of pool",
                        type=str,
                        default="")
    parser.add_argument(
        "-t",
        "--tmp_dir",
        help=
        "Temporary directory for plotting files (relative to final directory)",
        type=Path,
        default=Path("./plots.tmp"),
    )

    new_plots_root = path_from_root(
        root_path,
        load_config(root_path,
                    "config.yaml").get("harvester",
                                       {}).get("new_plot_root", "plots"),
    )
    parser.add_argument(
        "-d",
        "--final_dir",
        help="Final directory for plots (relative or absolute)",
        type=Path,
        default=new_plots_root,
    )

    # We need the keys file, to access pool keys (if the exist), and the sk_seed.
    args = parser.parse_args()
    if not key_config_filename.exists():
        raise RuntimeError("Keys not generated. Run chia-generate-keys")

    # The seed is what will be used to generate a private key for each plot
    key_config = load_config(root_path, key_config_filename)
    sk_seed: bytes = bytes.fromhex(key_config["sk_seed"])

    pool_pk: PublicKey
    if len(args.pool_pub_key) > 0:
        # Use the provided pool public key, useful for using an external pool
        pool_pk = PublicKey.from_bytes(bytes.fromhex(args.pool_pub_key))
    else:
        # Use the pool public key from the config, useful for solo farming
        pool_sk = PrivateKey.from_bytes(
            bytes.fromhex(key_config["pool_sks"][0]))
        pool_pk = pool_sk.get_public_key()

    print(
        f"Creating {args.num_plots} plots, from index {args.index} to "
        f"{args.index + args.num_plots - 1}, of size {args.size}, sk_seed {sk_seed.hex()} ppk {pool_pk}"
    )

    tmp_dir = args.final_dir / args.tmp_dir
    mkdir(tmp_dir)
    mkdir(args.final_dir)
    for i in range(args.index, args.index + args.num_plots):
        # Generate a sk based on the seed, plot size (k), and index
        sk: PrivateKey = PrivateKey.from_seed(sk_seed +
                                              args.size.to_bytes(1, "big") +
                                              i.to_bytes(4, "big"))

        # The plot seed is based on the pool and plot pks
        plot_seed: bytes32 = ProofOfSpace.calculate_plot_seed(
            pool_pk, sk.get_public_key())
        filename: str = f"plot-{i}-{args.size}-{plot_seed}.dat"
        full_path: Path = args.final_dir / filename
        if not full_path.exists():
            # Creates the plot. This will take a long time for larger plots.
            plotter: DiskPlotter = DiskPlotter()
            plotter.create_plot_disk(
                str(tmp_dir),
                str(args.final_dir),
                filename,
                args.size,
                bytes([]),
                plot_seed,
            )
        else:
            print(f"Plot {filename} already exists")

        # Updates the config if necessary.
        plot_config = load_config(root_path, plot_config_filename)
        plot_config_plots_new = deepcopy(plot_config.get("plots", []))
        relative_path = make_path_relative(full_path, root_path)
        if (relative_path not in plot_config_plots_new
                and full_path not in plot_config_plots_new):
            plot_config_plots_new[str(full_path)] = {
                "sk": bytes(sk).hex(),
                "pool_pk": bytes(pool_pk).hex(),
            }
        plot_config["plots"].update(plot_config_plots_new)

        # Dumps the new config to disk.
        save_config(root_path, plot_config_filename, plot_config)
    try:
        tmp_dir.rmdir()
    except Exception:
        print(f"warning: couldn't delete {tmp_dir}")
예제 #5
0
def main():
    """
    Script for creating plots and adding them to the plot config file.
    """
    root_path = DEFAULT_ROOT_PATH
    plot_config_filename = config_path_for_filename(root_path, "plots.yaml")

    parser = argparse.ArgumentParser(description="Chia plotting script.")
    parser.add_argument("-k", "--size", help="Plot size", type=int, default=26)
    parser.add_argument(
        "-n", "--num_plots", help="Number of plots", type=int, default=1
    )
    parser.add_argument(
        "-i", "--index", help="First plot index", type=int, default=None
    )
    parser.add_argument(
        "-p", "--pool_pub_key", help="Hex public key of pool", type=str, default=""
    )
    parser.add_argument(
        "-s", "--sk_seed", help="Secret key seed in hex", type=str, default=None
    )
    parser.add_argument(
        "-t",
        "--tmp_dir",
        help="Temporary directory for plotting files",
        type=Path,
        default=Path("."),
    )
    parser.add_argument(
        "-2",
        "--tmp2_dir",
        help="Second temporary directory for plotting files",
        type=Path,
        default=Path("."),
    )
    new_plots_root = path_from_root(
        root_path,
        load_config(root_path, "config.yaml")
        .get("harvester", {})
        .get("new_plot_root", "plots"),
    )
    parser.add_argument(
        "-d",
        "--final_dir",
        help="Final directory for plots (relative or absolute)",
        type=Path,
        default=new_plots_root,
    )

    args = parser.parse_args()

    if args.sk_seed is None and args.index is not None:
        log(
            f"You have specified the -i (index) argument without the -s (sk_seed) argument."
            f" The program has changes, so that the sk_seed is now generated randomly, so -i is no longer necessary."
            f" Please run the program without -i."
        )
        quit()

    if args.index is None:
        args.index = 0

    # The seed is what will be used to generate a private key for each plot
    if args.sk_seed is not None:
        sk_seed: bytes = bytes.fromhex(args.sk_seed)
        log(f"Using the provided sk_seed {sk_seed.hex()}.")
    else:
        sk_seed = token_bytes(32)
        log(
            f"Using sk_seed {sk_seed.hex()}. Note that sk seed is now generated randomly, as opposed "
            f"to from keys.yaml. If you want to use a specific seed, use the -s argument."
        )

    pool_pk: PublicKey
    if len(args.pool_pub_key) > 0:
        # Use the provided pool public key, useful for using an external pool
        pool_pk = PublicKey.from_bytes(bytes.fromhex(args.pool_pub_key))
    else:
        # Use the pool public key from the config, useful for solo farming
        keychain = Keychain()
        all_public_keys = keychain.get_all_public_keys()
        if len(all_public_keys) == 0:
            raise RuntimeError(
                "There are no private keys in the keychain, so we cannot create a plot. "
                "Please generate keys using 'chia keys generate' or pass in a pool pk with -p"
            )
        pool_pk = all_public_keys[0].get_public_key()

    log(
        f"Creating {args.num_plots} plots, from index {args.index} to "
        f"{args.index + args.num_plots - 1}, of size {args.size}, sk_seed {sk_seed.hex()} ppk {pool_pk}"
    )

    mkdir(args.tmp_dir)
    mkdir(args.tmp2_dir)
    mkdir(args.final_dir)
    finished_filenames = []
    for i in range(args.index, args.index + args.num_plots):
        # Generate a sk based on the seed, plot size (k), and index
        sk: PrivateKey = PrivateKey.from_seed(
            sk_seed + args.size.to_bytes(1, "big") + i.to_bytes(4, "big")
        )

        # The plot seed is based on the pool and plot pks
        plot_seed: bytes32 = ProofOfSpace.calculate_plot_seed(
            pool_pk, sk.get_public_key()
        )
        dt_string = datetime.now().strftime("%Y-%m-%d-%H-%M")

        filename: str = f"plot-k{args.size}-{dt_string}-{plot_seed}.dat"
        full_path: Path = args.final_dir / filename

        plot_config = load_config(root_path, plot_config_filename)
        plot_config_plots_new = deepcopy(plot_config.get("plots", []))
        filenames = [Path(k).name for k in plot_config_plots_new.keys()]
        already_in_config = any(plot_seed.hex() in fname for fname in filenames)
        if already_in_config:
            log(f"Plot {filename} already exists (in config)")
            continue

        if not full_path.exists():
            # Creates the plot. This will take a long time for larger plots.
            plotter: DiskPlotter = DiskPlotter()
            plotter.create_plot_disk(
                str(args.tmp_dir),
                str(args.tmp2_dir),
                str(args.final_dir),
                filename,
                args.size,
                bytes([]),
                plot_seed,
            )
            finished_filenames.append(filename)
        else:
            log(f"Plot {filename} already exists")

        # Updates the config if necessary.
        plot_config = load_config(root_path, plot_config_filename)
        plot_config_plots_new = deepcopy(plot_config.get("plots", []))
        plot_config_plots_new[str(full_path)] = {
            "sk": bytes(sk).hex(),
            "pool_pk": bytes(pool_pk).hex(),
        }
        plot_config["plots"].update(plot_config_plots_new)

        # Dumps the new config to disk.
        save_config(root_path, plot_config_filename, plot_config)
    log("")
    log("Summary:")
    try:
        args.tmp_dir.rmdir()
    except Exception:
        log(
            f"warning: did not remove primary temporary folder {args.tmp_dir}, it may not be empty."
        )
    try:
        args.tmp2_dir.rmdir()
    except Exception:
        log(
            f"warning: did not remove secondary temporary folder {args.tmp2_dir}, it may not be empty."
        )
    log(f"Created a total of {len(finished_filenames)} new plots")
    for filename in finished_filenames:
        log(filename)
예제 #6
0
    async def test1(self, simulation):
        test_rpc_port = uint16(21522)
        test_rpc_port_2 = uint16(21523)
        full_node_1, _, harvester, farmer, _, _, _ = simulation

        def stop_node_cb():
            pass

        def stop_node_cb_2():
            pass

        rpc_cleanup = await start_farmer_rpc_server(farmer, stop_node_cb,
                                                    test_rpc_port)
        rpc_cleanup_2 = await start_harvester_rpc_server(
            harvester, stop_node_cb_2, test_rpc_port_2)

        try:
            client = await FarmerRpcClient.create(test_rpc_port)
            client_2 = await HarvesterRpcClient.create(test_rpc_port_2)

            await asyncio.sleep(3)
            assert len(await client.get_connections()) == 2

            challenges = await client.get_latest_challenges()
            assert len(challenges) > 0

            res = await client_2.get_plots()
            num_plots = len(res["plots"])
            assert num_plots > 0
            plot_dir = get_plot_dir()
            plotter = DiskPlotter()
            pool_pk = harvester.pool_pubkeys[0]
            plot_sk = PrivateKey.from_seed(b"Farmer harvester rpc test seed")
            plot_seed = ProofOfSpace.calculate_plot_seed(
                pool_pk, plot_sk.get_public_key())
            filename = "test_farmer_harvester_rpc_plot.dat"
            plotter.create_plot_disk(
                str(plot_dir),
                str(plot_dir),
                str(plot_dir),
                filename,
                18,
                b"genesis",
                plot_seed,
                2 * 1024,
            )
            await client_2.add_plot(str(plot_dir / filename), plot_sk)

            res_2 = await client_2.get_plots()
            assert len(res_2["plots"]) == num_plots + 1

            await client_2.delete_plot(str(plot_dir / filename))
            res_3 = await client_2.get_plots()
            assert len(res_3["plots"]) == num_plots

            filename = "test_farmer_harvester_rpc_plot_2.dat"
            plotter.create_plot_disk(
                str(plot_dir),
                str(plot_dir),
                str(plot_dir),
                filename,
                18,
                b"genesis",
                plot_seed,
                2 * 1024,
            )
            await client_2.add_plot(str(plot_dir / filename), plot_sk, pool_pk)
            assert len((await client_2.get_plots())["plots"]) == num_plots + 1
            await client_2.delete_plot(str(plot_dir / filename))
            assert len((await client_2.get_plots())["plots"]) == num_plots

        except AssertionError:
            # Checks that the RPC manages to stop the node
            client.close()
            client_2.close()
            await client.await_closed()
            await client_2.await_closed()
            await rpc_cleanup()
            await rpc_cleanup_2()
            raise

        client.close()
        client_2.close()
        await client.await_closed()
        await client_2.await_closed()
        await rpc_cleanup()
        await rpc_cleanup_2()
예제 #7
0
def main():
    """
    Script for creating plots and adding them to the plot config file.
    """

    parser = argparse.ArgumentParser(description="Chia plotting script.")
    parser.add_argument("-k", "--size", help="Plot size", type=int, default=20)
    parser.add_argument("-n",
                        "--num_plots",
                        help="Number of plots",
                        type=int,
                        default=10)
    parser.add_argument("-p",
                        "--pool_pub_key",
                        help="Hex public key of pool",
                        type=str,
                        default="")
    parser.add_argument(
        "-t",
        "--tmp_dir",
        help="Temporary directory for plotting files (relative or absolute)",
        type=str,
        default="./plots",
    )
    parser.add_argument(
        "-d",
        "--final_dir",
        help="Final directory for plots (relative or absolute)",
        type=str,
        default="./plots",
    )

    # We need the keys file, to access pool keys (if the exist), and the sk_seed.
    args = parser.parse_args()
    if not os.path.isfile(key_config_filename):
        raise RuntimeError(
            "Keys not generated. Run python3 ./scripts/regenerate_keys.py.")

    # The seed is what will be used to generate a private key for each plot
    key_config = safe_load(open(key_config_filename, "r"))
    sk_seed: bytes = bytes.fromhex(key_config["sk_seed"])

    pool_pk: PublicKey
    if len(args.pool_pub_key) > 0:
        # Use the provided pool public key, useful for using an external pool
        pool_pk = PublicKey.from_bytes(bytes.fromhex(args.pool_pub_key))
    else:
        # Use the pool public key from the config, useful for solo farming
        pool_sk = PrivateKey.from_bytes(
            bytes.fromhex(key_config["pool_sks"][0]))
        pool_pk = pool_sk.get_public_key()

    print(
        f"Creating {args.num_plots} plots of size {args.size}, sk_seed {sk_seed.hex()} ppk {pool_pk}"
    )

    for i in range(args.num_plots):
        # Generate a sk based on the seed, plot size (k), and index
        sk: PrivateKey = PrivateKey.from_seed(sk_seed +
                                              args.size.to_bytes(1, "big") +
                                              i.to_bytes(4, "big"))

        # The plot seed is based on the pool and plot pks
        plot_seed: bytes32 = ProofOfSpace.calculate_plot_seed(
            pool_pk, sk.get_public_key())
        filename: str = f"plot-{i}-{args.size}-{plot_seed}.dat"
        full_path: str = os.path.join(args.final_dir, filename)
        if os.path.isfile(full_path):
            print(f"Plot {filename} already exists")
        else:
            # Creates the plot. This will take a long time for larger plots.
            plotter: DiskPlotter = DiskPlotter()
            plotter.create_plot_disk(args.tmp_dir, args.final_dir, filename,
                                     args.size, bytes([]), plot_seed)

        # Updates the config if necessary.
        if os.path.isfile(plot_config_filename):
            plot_config = safe_load(open(plot_config_filename, "r"))
        else:
            plot_config = {"plots": {}}
        plot_config_plots_new = deepcopy(plot_config["plots"])
        if full_path not in plot_config_plots_new:
            plot_config_plots_new[full_path] = {
                "sk": bytes(sk).hex(),
                "pool_pk": bytes(pool_pk).hex(),
            }
        plot_config["plots"].update(plot_config_plots_new)

        # Dumps the new config to disk.
        with open(plot_config_filename, "w") as f:
            safe_dump(plot_config, f)
예제 #8
0
    def __init__(
        self, root_path: Path = TEST_ROOT_PATH, real_plots: bool = False,
    ):
        create_default_chia_config(root_path)
        initialize_ssl(root_path)
        self.root_path = root_path
        self.wallet_sk: PrivateKey = PrivateKey.from_seed(b"coinbase")
        self.coinbase_target = std_hash(bytes(self.wallet_sk.get_public_key()))
        self.fee_target = std_hash(bytes(self.wallet_sk.get_public_key()))
        self.n_wesolowski = uint8(0)

        if not real_plots:
            # No real plots supplied, so we will use the small test plots
            self.use_any_pos = True
            self.plot_config: Dict = {"plots": {}}
            # Can't go much lower than 19, since plots start having no solutions
            k: uint8 = uint8(19)
            # Uses many plots for testing, in order to guarantee proofs of space at every height
            num_plots = 40
            # Use the empty string as the seed for the private key
            pool_sk: PrivateKey = PrivateKey.from_seed(b"")
            pool_pk: PublicKey = pool_sk.get_public_key()
            plot_sks: List[PrivateKey] = [
                PrivateKey.from_seed(pn.to_bytes(4, "big")) for pn in range(num_plots)
            ]
            plot_pks: List[PublicKey] = [sk.get_public_key() for sk in plot_sks]

            plot_seeds: List[bytes32] = [
                ProofOfSpace.calculate_plot_seed(pool_pk, plot_pk)
                for plot_pk in plot_pks
            ]
            plot_dir = root_path / "plots"
            mkdir(plot_dir)
            filenames: List[str] = [
                f"genesis-plots-{k}{std_hash(int.to_bytes(i, 4, 'big')).hex()}.dat"
                for i in range(num_plots)
            ]
            done_filenames = set()
            temp_dir = plot_dir / "plot.tmp"
            mkdir(temp_dir)
            try:
                for pn, filename in enumerate(filenames):
                    if not (plot_dir / filename).exists():
                        plotter = DiskPlotter()
                        plotter.create_plot_disk(
                            str(plot_dir),
                            str(plot_dir),
                            str(plot_dir),
                            filename,
                            k,
                            b"genesis",
                            plot_seeds[pn],
                        )
                        done_filenames.add(filename)
                    self.plot_config["plots"][str(plot_dir / filename)] = {
                        "pool_pk": bytes(pool_pk).hex(),
                        "sk": bytes(plot_sks[pn]).hex(),
                        "pool_sk": bytes(pool_sk).hex(),
                    }
            except KeyboardInterrupt:
                for filename in filenames:
                    if (
                        filename not in done_filenames
                        and (plot_dir / filename).exists()
                    ):
                        (plot_dir / filename).unlink()
                sys.exit(1)
        else:
            # Real plots supplied, so we will use these instead of the test plots
            config = load_config_cli(root_path, "config.yaml", "harvester")
            try:
                key_config = load_config(root_path, "keys.yaml")
            except FileNotFoundError:
                raise RuntimeError("Keys not generated. Run `chia generate keys`")
            try:
                plot_config = load_config(root_path, "plots.yaml")
            except FileNotFoundError:
                raise RuntimeError("Plots not generated. Run chia-create-plots")

            pool_sks: List[PrivateKey] = [
                PrivateKey.from_bytes(bytes.fromhex(ce))
                for ce in key_config["pool_sks"]
            ]

            for key, value in plot_config["plots"].items():
                for pool_sk in pool_sks:
                    if bytes(pool_sk.get_public_key()).hex() == value["pool_pk"]:
                        plot_config["plots"][key]["pool_sk"] = bytes(pool_sk).hex()

            self.plot_config = plot_config
            self.use_any_pos = False
예제 #9
0
    def __init__(
        self,
        root_path: Path = TEST_ROOT_PATH,
        real_plots: bool = False,
    ):
        create_default_chia_config(root_path)
        initialize_ssl(root_path)
        self.root_path = root_path
        self.n_wesolowski = uint8(0)
        self.real_plots = real_plots

        if not real_plots:
            # No real plots supplied, so we will use the small test plots
            self.use_any_pos = True
            self.plot_config: Dict = {"plots": {}}
            # Can't go much lower than 19, since plots start having no solutions
            k: uint8 = uint8(19)
            # Uses many plots for testing, in order to guarantee proofs of space at every height
            num_plots = 40
            # Use the empty string as the seed for the private key

            self.keychain = Keychain("testing", True)
            self.keychain.delete_all_keys()
            self.keychain.add_private_key_seed(b"block_tools")
            pool_sk: PrivateKey = self.keychain.get_all_private_keys(
            )[0][0].get_private_key()
            pool_pk: PublicKey = pool_sk.get_public_key()

            plot_sks: List[PrivateKey] = [
                PrivateKey.from_seed(pn.to_bytes(4, "big"))
                for pn in range(num_plots)
            ]
            plot_pks: List[PublicKey] = [
                sk.get_public_key() for sk in plot_sks
            ]

            plot_seeds: List[bytes32] = [
                ProofOfSpace.calculate_plot_seed(pool_pk, plot_pk)
                for plot_pk in plot_pks
            ]
            plot_dir = get_plot_dir(root_path)
            mkdir(plot_dir)
            filenames: List[str] = [
                f"genesis-plots-{k}{std_hash(int.to_bytes(i, 4, 'big')).hex()}.dat"
                for i in range(num_plots)
            ]
            done_filenames = set()
            temp_dir = plot_dir / "plot.tmp"
            mkdir(temp_dir)
            try:
                for pn, filename in enumerate(filenames):
                    if not (plot_dir / filename).exists():
                        plotter = DiskPlotter()
                        plotter.create_plot_disk(
                            str(plot_dir),
                            str(plot_dir),
                            str(plot_dir),
                            filename,
                            k,
                            b"genesis",
                            plot_seeds[pn],
                        )
                        done_filenames.add(filename)
                    self.plot_config["plots"][str(plot_dir / filename)] = {
                        "pool_pk": bytes(pool_pk).hex(),
                        "sk": bytes(plot_sks[pn]).hex(),
                        "pool_sk": bytes(pool_sk).hex(),
                    }
                save_config(self.root_path, "plots.yaml", self.plot_config)

            except KeyboardInterrupt:
                for filename in filenames:
                    if (filename not in done_filenames
                            and (plot_dir / filename).exists()):
                        (plot_dir / filename).unlink()
                sys.exit(1)
        else:
            try:
                plot_config = load_config(DEFAULT_ROOT_PATH, "plots.yaml")
                normal_config = load_config(DEFAULT_ROOT_PATH, "config.yaml")
            except FileNotFoundError:
                raise RuntimeError(
                    "Plots not generated. Run chia-create-plots")
            self.keychain = Keychain(testing=False)
            private_keys: List[PrivateKey] = [
                k.get_private_key()
                for (k, _) in self.keychain.get_all_private_keys()
            ]
            pool_pubkeys: List[PublicKey] = [
                sk.get_public_key() for sk in private_keys
            ]
            if len(private_keys) == 0:
                raise RuntimeError(
                    "Keys not generated. Run `chia generate keys`")

            self.prover_dict, _, _ = load_plots(normal_config["harvester"],
                                                plot_config, pool_pubkeys,
                                                DEFAULT_ROOT_PATH)

            new_plot_config: Dict = {"plots": {}}
            for key, value in plot_config["plots"].items():
                for sk in private_keys:
                    if (bytes(sk.get_public_key()).hex() == value["pool_pk"]
                            and key in self.prover_dict):
                        new_plot_config["plots"][key] = value
                        new_plot_config["plots"][key]["pool_sk"] = bytes(
                            sk).hex()

            self.plot_config = new_plot_config
            self.use_any_pos = False
            a = self.plot_config["plots"]
            print(f"Using {len(a)} reals plots to initialize block_tools")

        private_key = self.keychain.get_all_private_keys()[0][0]
        self.fee_target = create_puzzlehash_for_pk(
            BLSPublicKey(bytes(private_key.public_child(1).get_public_key())))