mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-09-07 02:24:15 -05:00
Use pathlib.Path instead of os.path
This commit is contained in:
+2
-2
@@ -64,8 +64,8 @@ full_node:
|
||||
host: 127.0.0.1
|
||||
port: 8444
|
||||
|
||||
# Run multiple nodes with different databases by changing the database_id
|
||||
database_id: 1
|
||||
# Run multiple nodes with different databases by changing the database_path
|
||||
database_path: blockchain_v2_1.db
|
||||
|
||||
# If True, starts an RPC server at the following port
|
||||
start_rpc_server: True
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
ROOT_DIR = Path(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import unittest
|
||||
from chiapos import DiskProver, DiskPlotter, Verifier
|
||||
from hashlib import sha256
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class TestPythonBindings(unittest.TestCase):
|
||||
@@ -14,7 +14,7 @@ class TestPythonBindings(unittest.TestCase):
|
||||
|
||||
pl = DiskPlotter()
|
||||
pl.create_plot_disk(".", ".", "myplot.dat", 21, bytes([1, 2, 3, 4, 5]), plot_seed)
|
||||
pr = DiskProver("./myplot.dat")
|
||||
pr = DiskProver(str(Path("myplot.dat")))
|
||||
|
||||
total_proofs: int = 0
|
||||
iterations: int = 5000
|
||||
@@ -32,7 +32,7 @@ class TestPythonBindings(unittest.TestCase):
|
||||
print(f"total proofs {total_proofs} out of {iterations}\
|
||||
{total_proofs / iterations}")
|
||||
assert total_proofs == 4647
|
||||
os.remove("myplot.dat")
|
||||
Path("myplot.dat").unlink()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
import argparse
|
||||
import os
|
||||
from hashlib import sha256
|
||||
from pathlib import Path
|
||||
|
||||
from blspy import PrivateKey, PublicKey
|
||||
from yaml import safe_load
|
||||
@@ -10,8 +10,8 @@ from definitions import ROOT_DIR
|
||||
from src.types.proof_of_space import ProofOfSpace
|
||||
from src.types.sized_bytes import bytes32
|
||||
|
||||
plot_root = os.path.join(ROOT_DIR, "plots")
|
||||
plot_config_filename = os.path.join(ROOT_DIR, "config", "plots.yaml")
|
||||
plot_root = ROOT_DIR / "plots"
|
||||
plot_config_filename = ROOT_DIR / "config" / "plots.yaml"
|
||||
|
||||
|
||||
def main():
|
||||
@@ -26,23 +26,23 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
v = Verifier()
|
||||
if os.path.isfile(plot_config_filename):
|
||||
if plot_config_filename.exists():
|
||||
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):
|
||||
if not Path(plot_filename).exists():
|
||||
# Tries relative path
|
||||
full_path: str = os.path.join(plot_root, plot_filename)
|
||||
if not os.path.isfile(full_path):
|
||||
full_path: Path = plot_root / plot_filename
|
||||
if not full_path.exists():
|
||||
# Tries absolute path
|
||||
full_path: str = plot_filename
|
||||
if not os.path.isfile(full_path):
|
||||
full_path: Path = plot_filename
|
||||
if not full_path.exists():
|
||||
print(f"Plot file {full_path} not found.")
|
||||
continue
|
||||
pr = DiskProver(full_path)
|
||||
pr = DiskProver(str(full_path))
|
||||
else:
|
||||
pr = DiskProver(plot_filename)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import argparse
|
||||
import os
|
||||
from copy import deepcopy
|
||||
from pathlib import Path
|
||||
|
||||
from blspy import PrivateKey, PublicKey
|
||||
from yaml import safe_dump, safe_load
|
||||
@@ -10,8 +10,8 @@ from definitions import ROOT_DIR
|
||||
from src.types.proof_of_space import ProofOfSpace
|
||||
from src.types.sized_bytes import bytes32
|
||||
|
||||
plot_config_filename = os.path.join(ROOT_DIR, "config", "plots.yaml")
|
||||
key_config_filename = os.path.join(ROOT_DIR, "config", "keys.yaml")
|
||||
plot_config_filename = ROOT_DIR / "config" / "plots.yaml"
|
||||
key_config_filename = ROOT_DIR / "config" / "keys.yaml"
|
||||
|
||||
|
||||
def main():
|
||||
@@ -44,7 +44,7 @@ def main():
|
||||
|
||||
# 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):
|
||||
if not key_config_filename.exists():
|
||||
raise RuntimeError(
|
||||
"Keys not generated. Run python3 ./scripts/regenerate_keys.py."
|
||||
)
|
||||
@@ -76,9 +76,9 @@ def main():
|
||||
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):
|
||||
filename: Path = Path(f"plot-{i}-{args.size}-{plot_seed}.dat")
|
||||
full_path: Path = args.final_dir / filename
|
||||
if full_path.exists():
|
||||
print(f"Plot {filename} already exists")
|
||||
else:
|
||||
# Creates the plot. This will take a long time for larger plots.
|
||||
@@ -88,7 +88,7 @@ def main():
|
||||
)
|
||||
|
||||
# Updates the config if necessary.
|
||||
if os.path.isfile(plot_config_filename):
|
||||
if plot_config_filename.exists():
|
||||
plot_config = safe_load(open(plot_config_filename, "r"))
|
||||
else:
|
||||
plot_config = {"plots": {}}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import argparse
|
||||
import os
|
||||
from hashlib import sha256
|
||||
from secrets import token_bytes
|
||||
|
||||
@@ -8,7 +7,7 @@ from yaml import safe_dump, safe_load
|
||||
|
||||
from definitions import ROOT_DIR
|
||||
|
||||
key_config_filename = os.path.join(ROOT_DIR, "config", "keys.yaml")
|
||||
key_config_filename = ROOT_DIR / "config" / "keys.yaml"
|
||||
|
||||
|
||||
def str2bool(v: str) -> bool:
|
||||
@@ -57,7 +56,7 @@ def main():
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if os.path.isfile(key_config_filename):
|
||||
if key_config_filename.exists():
|
||||
# If the file exists, warn the user
|
||||
yn = input(
|
||||
f"The keys file {key_config_filename} already exists. Are you sure"
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
_run_bg_cmd python -m src.server.start_harvester
|
||||
_run_bg_cmd python -m src.server.start_timelord
|
||||
_run_bg_cmd python -m src.server.start_farmer
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_id=1 --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8222 --rpc_port=8555
|
||||
|
||||
wait
|
||||
|
||||
@@ -12,8 +12,8 @@ _run_bg_cmd python -m src.server.start_harvester
|
||||
_run_bg_cmd python -m src.server.start_timelord
|
||||
_run_bg_cmd python -m src.server.start_farmer
|
||||
_run_bg_cmd python -m src.server.start_introducer
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_id=1 --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555 --introducer_peer.host="127.0.0.1" --introducer_peer.port=8445
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8002 --database_id=2 --rpc_port=8556 --introducer_peer.host="127.0.0.1" --introducer_peer.port=8445
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_path="simulation_db_1" --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555 --introducer_peer.host="127.0.0.1" --introducer_peer.port=8445
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8002 --database_path="simulation_db_2" --rpc_port=8556 --introducer_peer.host="127.0.0.1" --introducer_peer.port=8445
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8222 --rpc_port=8555
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8223 --rpc_port=8556
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
_run_bg_cmd python -m src.server.start_harvester
|
||||
_run_bg_cmd python -m src.server.start_farmer
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_id=1 --connect_to_farmer=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --connect_to_farmer=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8222 --rpc_port=8555
|
||||
|
||||
wait
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
. scripts/common.sh
|
||||
|
||||
# Starts a full node
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_id=1 --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --connect_to_farmer=True --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8222 --rpc_port=8555
|
||||
|
||||
wait
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Starts a timelord, and a full node
|
||||
|
||||
_run_bg_cmd python -m src.server.start_timelord
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --database_id=1 --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.server.start_full_node --port=8444 --connect_to_timelord=True --rpc_port=8555
|
||||
_run_bg_cmd python -m src.ui.start_ui --port=8222 --rpc_port=8555
|
||||
|
||||
wait
|
||||
|
||||
+30
-4
@@ -73,15 +73,13 @@ class Blockchain:
|
||||
|
||||
@staticmethod
|
||||
async def create(
|
||||
headers_input: Dict[str, SmallHeaderBlock],
|
||||
unspent_store: UnspentStore,
|
||||
store: FullNodeStore,
|
||||
override_constants: Dict = {},
|
||||
):
|
||||
"""
|
||||
Initializes a blockchain with the given header blocks, assuming they have all been
|
||||
validated. If no header_blocks are given, only the genesis block is added.
|
||||
Uses the genesis block given in override_constants, or as a fallback,
|
||||
Initializes a blockchain with the header blocks from disk, assuming they have all been
|
||||
validated. Uses the genesis block given in override_constants, or as a fallback,
|
||||
in the consensus constants config.
|
||||
"""
|
||||
self = Blockchain()
|
||||
@@ -101,6 +99,10 @@ class Blockchain:
|
||||
if result != ReceiveBlockResult.ADDED_TO_HEAD:
|
||||
raise InvalidGenesisBlock()
|
||||
|
||||
headers_input: Dict[
|
||||
str, SmallHeaderBlock
|
||||
] = await self.load_header_blocks_from_store()
|
||||
|
||||
assert self.lca_block is not None
|
||||
if len(headers_input) > 0:
|
||||
self.headers = headers_input
|
||||
@@ -118,6 +120,30 @@ class Blockchain:
|
||||
)
|
||||
return self
|
||||
|
||||
async def load_header_blocks_from_store(self) -> Dict[str, SmallHeaderBlock]:
|
||||
"""
|
||||
Loads headers from disk, into a list of SmallHeaderBlocks, that can be used
|
||||
to initialize the Blockchain class.
|
||||
"""
|
||||
seen_blocks: Dict[str, SmallHeaderBlock] = {}
|
||||
tips: List[SmallHeaderBlock] = []
|
||||
for small_header_block in await self.store.get_small_header_blocks():
|
||||
if not tips or small_header_block.weight > tips[0].weight:
|
||||
tips = [small_header_block]
|
||||
seen_blocks[small_header_block.header_hash] = small_header_block
|
||||
|
||||
header_blocks = {}
|
||||
if len(tips) > 0:
|
||||
curr: SmallHeaderBlock = tips[0]
|
||||
reverse_blocks: List[SmallHeaderBlock] = [curr]
|
||||
while curr.height > 0:
|
||||
curr = seen_blocks[curr.prev_header_hash]
|
||||
reverse_blocks.append(curr)
|
||||
|
||||
for block in reversed(reverse_blocks):
|
||||
header_blocks[block.header_hash] = block
|
||||
return header_blocks
|
||||
|
||||
def get_current_tips(self) -> List[SmallHeaderBlock]:
|
||||
"""
|
||||
Return the heads.
|
||||
|
||||
+11
-15
@@ -1,7 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
from blspy import PrependSignature, PrivateKey, PublicKey, Util
|
||||
@@ -25,10 +24,10 @@ class Harvester:
|
||||
self.plot_config: Dict = plot_config
|
||||
|
||||
# From filename to prover
|
||||
self.provers: Dict[str, DiskProver] = {}
|
||||
self.provers: Dict[Path, DiskProver] = {}
|
||||
|
||||
# From quality to (challenge_hash, filename, index)
|
||||
self.challenge_hashes: Dict[bytes32, Tuple[bytes32, str, uint8]] = {}
|
||||
self.challenge_hashes: Dict[bytes32, Tuple[bytes32, Path, uint8]] = {}
|
||||
self._plot_notification_task = asyncio.create_task(self._plot_notification())
|
||||
self._is_shutdown: bool = False
|
||||
|
||||
@@ -59,16 +58,13 @@ class Harvester:
|
||||
which must be put into the plots, before the plotting process begins. We cannot
|
||||
use any plots which don't have one of the pool keys.
|
||||
"""
|
||||
for partial_filename, plot_config in self.plot_config["plots"].items():
|
||||
for partial_filename_str, plot_config in self.plot_config["plots"].items():
|
||||
partial_filename = Path(partial_filename_str)
|
||||
potential_filenames = [partial_filename]
|
||||
if "plot_root" in self.config:
|
||||
potential_filenames.append(
|
||||
os.path.join(self.config["plot_root"], partial_filename)
|
||||
)
|
||||
potential_filenames.append(self.config["plot_root"] / partial_filename)
|
||||
else:
|
||||
potential_filenames.append(
|
||||
os.path.join(ROOT_DIR, "plots", partial_filename)
|
||||
)
|
||||
potential_filenames.append(ROOT_DIR / "plots" / partial_filename)
|
||||
pool_pubkey = PublicKey.from_bytes(bytes.fromhex(plot_config["pool_pk"]))
|
||||
|
||||
# Only use plots that correct pools associated with them
|
||||
@@ -80,8 +76,8 @@ class Harvester:
|
||||
|
||||
found = False
|
||||
for filename in potential_filenames:
|
||||
if os.path.isfile(filename):
|
||||
self.provers[partial_filename] = DiskProver(filename)
|
||||
if filename.exists():
|
||||
self.provers[partial_filename] = DiskProver(str(filename))
|
||||
log.info(
|
||||
f"Farming plot {filename} of size {self.provers[partial_filename].get_size()}"
|
||||
)
|
||||
@@ -108,7 +104,7 @@ class Harvester:
|
||||
)
|
||||
except RuntimeError:
|
||||
log.error("Error using prover object. Reinitializing prover object.")
|
||||
self.provers[filename] = DiskProver(filename)
|
||||
self.provers[filename] = DiskProver(str(filename))
|
||||
quality_strings = prover.get_qualities_for_challenge(
|
||||
new_challenge.challenge_hash
|
||||
)
|
||||
@@ -152,7 +148,7 @@ class Harvester:
|
||||
try:
|
||||
proof_xs = self.provers[filename].get_full_proof(challenge_hash, index)
|
||||
except RuntimeError:
|
||||
self.provers[filename] = DiskProver(filename)
|
||||
self.provers[filename] = DiskProver(str(filename))
|
||||
proof_xs = self.provers[filename].get_full_proof(challenge_hash, index)
|
||||
pool_pubkey = PublicKey.from_bytes(
|
||||
bytes.fromhex(self.plot_config["plots"][filename]["pool_pk"])
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import asyncio
|
||||
import concurrent
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
from secrets import token_bytes
|
||||
from typing import Any, AsyncGenerator, List, Optional, Tuple
|
||||
@@ -32,7 +31,7 @@ from src.util.errors import (
|
||||
from src.util.ints import uint16
|
||||
from src.util.network import create_node_id
|
||||
|
||||
config_filename = os.path.join(ROOT_DIR, "config", "config.yaml")
|
||||
config_filename = ROOT_DIR / "config" / "config.yaml"
|
||||
config = safe_load(open(config_filename, "r"))
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import asyncio
|
||||
import logging
|
||||
import logging.config
|
||||
import signal
|
||||
from typing import List, Dict
|
||||
from pathlib import Path
|
||||
|
||||
import miniupnpc
|
||||
|
||||
@@ -20,7 +20,6 @@ from src.mempool import Mempool
|
||||
from src.server.server import ChiaServer
|
||||
from src.server.connection import NodeType
|
||||
from src.types.full_block import FullBlock
|
||||
from src.types.header_block import SmallHeaderBlock
|
||||
from src.types.peer_info import PeerInfo
|
||||
from src.unspent_store import UnspentStore
|
||||
from src.util.logging import initialize_logging
|
||||
@@ -28,29 +27,6 @@ from src.util.config import load_config_cli
|
||||
from setproctitle import setproctitle
|
||||
|
||||
|
||||
async def load_header_blocks_from_store(
|
||||
store: FullNodeStore,
|
||||
) -> Dict[str, SmallHeaderBlock]:
|
||||
seen_blocks: Dict[str, SmallHeaderBlock] = {}
|
||||
tips: List[SmallHeaderBlock] = []
|
||||
for small_header_block in await store.get_small_header_blocks():
|
||||
if not tips or small_header_block.weight > tips[0].weight:
|
||||
tips = [small_header_block]
|
||||
seen_blocks[small_header_block.header_hash] = small_header_block
|
||||
|
||||
header_blocks = {}
|
||||
if len(tips) > 0:
|
||||
curr: SmallHeaderBlock = tips[0]
|
||||
reverse_blocks: List[SmallHeaderBlock] = [curr]
|
||||
while curr.height > 0:
|
||||
curr = seen_blocks[curr.prev_header_hash]
|
||||
reverse_blocks.append(curr)
|
||||
|
||||
for block in reversed(reverse_blocks):
|
||||
header_blocks[block.header_hash] = block
|
||||
return header_blocks
|
||||
|
||||
|
||||
async def main():
|
||||
config = load_config_cli("config.yaml", "full_node")
|
||||
setproctitle("chia_full_node")
|
||||
@@ -59,20 +35,17 @@ async def main():
|
||||
log = logging.getLogger(__name__)
|
||||
server_closed = False
|
||||
|
||||
db_name = f"blockchain_v2_{config['database_id']}.db"
|
||||
db_path = Path(config["database_path"])
|
||||
|
||||
# Create the store (DB) and full node instance
|
||||
store = await FullNodeStore.create(db_name)
|
||||
store = await FullNodeStore.create(db_path)
|
||||
|
||||
genesis: FullBlock = FullBlock.from_bytes(constants["GENESIS_BLOCK"])
|
||||
await store.add_block(genesis)
|
||||
unspent_store = await UnspentStore.create(db_path)
|
||||
|
||||
log.info("Initializing blockchain from disk")
|
||||
small_header_blocks: Dict[
|
||||
str, SmallHeaderBlock
|
||||
] = await load_header_blocks_from_store(store)
|
||||
|
||||
unspent_store = await UnspentStore.create(db_name)
|
||||
blockchain = await Blockchain.create(small_header_blocks, unspent_store, store)
|
||||
blockchain = await Blockchain.create(unspent_store, store)
|
||||
|
||||
mempool = Mempool(unspent_store)
|
||||
# await mempool.initialize() TODO uncomment once it's implemented
|
||||
@@ -110,7 +83,7 @@ async def main():
|
||||
server_closed = True
|
||||
|
||||
if config["start_rpc_server"]:
|
||||
# Starts the RPC server if -r is provided
|
||||
# Starts the RPC server
|
||||
rpc_cleanup = await start_rpc_server(
|
||||
full_node, master_close_cb, config["rpc_port"]
|
||||
)
|
||||
|
||||
+3
-4
@@ -1,6 +1,7 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import aiosqlite
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
from blspy import PublicKey
|
||||
@@ -16,7 +17,6 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FullNodeStore:
|
||||
db_name: str
|
||||
db: aiosqlite.Connection
|
||||
# Whether or not we are syncing
|
||||
sync_mode: bool
|
||||
@@ -50,12 +50,11 @@ class FullNodeStore:
|
||||
lock: asyncio.Lock
|
||||
|
||||
@classmethod
|
||||
async def create(cls, db_name: str):
|
||||
async def create(cls, db_path: Path):
|
||||
self = cls()
|
||||
self.db_name = db_name
|
||||
|
||||
# All full blocks which have been added to the blockchain. Header_hash -> block
|
||||
self.db = await aiosqlite.connect(self.db_name)
|
||||
self.db = await aiosqlite.connect(db_path)
|
||||
await self.db.execute(
|
||||
"CREATE TABLE IF NOT EXISTS blocks(height bigint, header_hash text PRIMARY KEY, block blob)"
|
||||
)
|
||||
|
||||
+2
-3
@@ -1,6 +1,5 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from typing import Callable, List, Optional, Tuple, Dict
|
||||
import aiohttp
|
||||
|
||||
@@ -114,8 +113,8 @@ class FullNodeUI:
|
||||
self.kb = self.setup_keybindings()
|
||||
self.style = Style([("error", "#ff0044")])
|
||||
self.pool_pks: List[PublicKey] = []
|
||||
key_config_filename = os.path.join(ROOT_DIR, "config", "keys.yaml")
|
||||
if os.path.isfile(key_config_filename):
|
||||
key_config_filename = ROOT_DIR / "config" / "keys.yaml"
|
||||
if key_config_filename.exists():
|
||||
config = safe_load(open(key_config_filename, "r"))
|
||||
|
||||
self.pool_pks = [
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
from typing import Dict, Optional, List
|
||||
from pathlib import Path
|
||||
import aiosqlite
|
||||
from src.types.full_block import FullBlock
|
||||
from src.types.hashable.Coin import Coin, CoinName
|
||||
@@ -29,7 +30,6 @@ class UnspentStore:
|
||||
DiffStores are updated/recreated. (managed by blockchain.py)
|
||||
"""
|
||||
|
||||
db_name: str
|
||||
unspent_db: aiosqlite.Connection
|
||||
# Whether or not we are syncing
|
||||
sync_mode: bool = False
|
||||
@@ -38,12 +38,11 @@ class UnspentStore:
|
||||
head_diffs: Dict[bytes32, DiffStore]
|
||||
|
||||
@classmethod
|
||||
async def create(cls, db_name: str):
|
||||
async def create(cls, db_path: Path):
|
||||
self = cls()
|
||||
self.db_name = db_name
|
||||
|
||||
# All full blocks which have been added to the blockchain. Header_hash -> block
|
||||
self.unspent_db = await aiosqlite.connect(self.db_name)
|
||||
self.unspent_db = await aiosqlite.connect(db_path)
|
||||
await self.unspent_db.execute(
|
||||
(
|
||||
f"CREATE TABLE IF NOT EXISTS unspent("
|
||||
|
||||
+1
-3
@@ -1,5 +1,3 @@
|
||||
import os
|
||||
|
||||
import yaml
|
||||
import argparse
|
||||
from typing import Dict, Any, Callable, Optional
|
||||
@@ -7,7 +5,7 @@ from definitions import ROOT_DIR
|
||||
|
||||
|
||||
def load_config(filename: str, sub_config: Optional[str] = None) -> Dict:
|
||||
config_filename = os.path.join(ROOT_DIR, "config", filename)
|
||||
config_filename = ROOT_DIR / "config" / filename
|
||||
if sub_config is not None:
|
||||
return yaml.safe_load(open(config_filename, "r"))[sub_config]
|
||||
else:
|
||||
|
||||
+9
-12
@@ -1,8 +1,8 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from hashlib import sha256
|
||||
from typing import Any, Dict, List, Tuple, Optional
|
||||
from pathlib import Path
|
||||
|
||||
import blspy
|
||||
from blspy import PrependSignature, PrivateKey, PublicKey
|
||||
@@ -57,7 +57,7 @@ class BlockTools:
|
||||
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.plot_dir = Path("tests") / "plots"
|
||||
self.filenames: List[str] = [
|
||||
"genesis-plots-"
|
||||
+ str(k)
|
||||
@@ -68,7 +68,7 @@ class BlockTools:
|
||||
done_filenames = set()
|
||||
try:
|
||||
for pn, filename in enumerate(self.filenames):
|
||||
if not os.path.exists(os.path.join(self.plot_dir, filename)):
|
||||
if not (self.plot_dir / filename).exists():
|
||||
plotter = DiskPlotter()
|
||||
plotter.create_plot_disk(
|
||||
self.plot_dir,
|
||||
@@ -81,10 +81,11 @@ class BlockTools:
|
||||
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)
|
||||
if (
|
||||
filename not in done_filenames
|
||||
and (self.plot_dir / filename).exists()
|
||||
):
|
||||
os.remove(os.path.join(self.plot_dir, filename))
|
||||
(self.plot_dir / filename).unlink()
|
||||
sys.exit(1)
|
||||
|
||||
def get_consecutive_blocks(
|
||||
@@ -351,7 +352,7 @@ class BlockTools:
|
||||
filename = self.filenames[seeded_pn]
|
||||
plot_pk = plot_pks[seeded_pn]
|
||||
plot_sk = plot_sks[seeded_pn]
|
||||
prover = DiskProver(os.path.join(self.plot_dir, filename))
|
||||
prover = DiskProver(str(self.plot_dir / filename))
|
||||
qualities = prover.get_qualities_for_challenge(challenge_hash)
|
||||
if len(qualities) > 0:
|
||||
break
|
||||
@@ -381,11 +382,7 @@ class BlockTools:
|
||||
output = ClassgroupElement(y_cl[0], y_cl[1])
|
||||
|
||||
proof_of_time = ProofOfTime(
|
||||
challenge_hash,
|
||||
number_iters,
|
||||
output,
|
||||
n_wesolowski,
|
||||
proof_bytes,
|
||||
challenge_hash, number_iters, output, n_wesolowski, proof_bytes,
|
||||
)
|
||||
|
||||
if not reward_puzzlehash:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import asyncio
|
||||
from typing import Any, Dict
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -46,19 +46,17 @@ class TestRpc:
|
||||
test_node_1_port = 21234
|
||||
test_node_2_port = 21235
|
||||
test_rpc_port = 21236
|
||||
db_filename = "blockchain_test"
|
||||
db_filename = Path("blockchain_test")
|
||||
|
||||
if os.path.isfile(db_filename):
|
||||
os.remove(db_filename)
|
||||
if db_filename.exists():
|
||||
db_filename.unlink()
|
||||
store = await FullNodeStore.create(db_filename)
|
||||
await store._clear_database()
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 10, [], 10)
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
mempool = Mempool(unspent_store)
|
||||
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
await store.add_block(blocks[0])
|
||||
for i in range(1, 9):
|
||||
assert (await b.receive_block(blocks[i], blocks[i - 1].header_block))[
|
||||
|
||||
+9
-13
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
from pathlib import Path
|
||||
|
||||
from src.blockchain import Blockchain
|
||||
from src.mempool import Mempool
|
||||
@@ -39,22 +39,18 @@ async def setup_two_nodes(dic={}):
|
||||
for k in dic.keys():
|
||||
test_constants[k] = dic[k]
|
||||
|
||||
store_1 = await FullNodeStore.create("blockchain_test")
|
||||
store_2 = await FullNodeStore.create("blockchain_test_2")
|
||||
store_1 = await FullNodeStore.create(Path("blockchain_test"))
|
||||
store_2 = await FullNodeStore.create(Path("blockchain_test_2"))
|
||||
await store_1._clear_database()
|
||||
await store_2._clear_database()
|
||||
unspent_store_1 = await UnspentStore.create("blockchain_test")
|
||||
unspent_store_2 = await UnspentStore.create("blockchain_test_2")
|
||||
unspent_store_1 = await UnspentStore.create(Path("blockchain_test"))
|
||||
unspent_store_2 = await UnspentStore.create(Path("blockchain_test_2"))
|
||||
await unspent_store_1._clear_database()
|
||||
await unspent_store_2._clear_database()
|
||||
mempool_1 = Mempool(unspent_store_1, dic)
|
||||
mempool_2 = Mempool(unspent_store_2, dic)
|
||||
b_1: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store_1, store_1, test_constants
|
||||
)
|
||||
b_2: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store_2, store_2, test_constants
|
||||
)
|
||||
b_1: Blockchain = await Blockchain.create(unspent_store_1, store_1, test_constants)
|
||||
b_2: Blockchain = await Blockchain.create(unspent_store_2, store_2, test_constants)
|
||||
await store_1.add_block(FullBlock.from_bytes(test_constants["GENESIS_BLOCK"]))
|
||||
await store_2.add_block(FullBlock.from_bytes(test_constants["GENESIS_BLOCK"]))
|
||||
|
||||
@@ -85,5 +81,5 @@ async def setup_two_nodes(dic={}):
|
||||
await store_2.close()
|
||||
await unspent_store_1.close()
|
||||
await unspent_store_2.close()
|
||||
os.remove("blockchain_test")
|
||||
os.remove("blockchain_test_2")
|
||||
Path("blockchain_test").unlink()
|
||||
Path("blockchain_test_2").unlink()
|
||||
|
||||
+23
-33
@@ -1,6 +1,7 @@
|
||||
import asyncio
|
||||
import time
|
||||
from typing import Any, Dict
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from blspy import PrivateKey
|
||||
@@ -45,10 +46,10 @@ def event_loop():
|
||||
class TestGenesisBlock:
|
||||
@pytest.mark.asyncio
|
||||
async def test_basic_blockchain(self):
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
bc1 = await Blockchain.create({}, unspent_store, store)
|
||||
bc1 = await Blockchain.create(unspent_store, store)
|
||||
assert len(bc1.get_current_tips()) == 1
|
||||
genesis_block = bc1.get_current_tips()[0]
|
||||
assert genesis_block.height == 0
|
||||
@@ -72,12 +73,10 @@ class TestBlockValidation:
|
||||
Provides a list of 10 valid blocks, as well as a blockchain with 9 blocks added to it.
|
||||
"""
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 10, [], 10)
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
for i in range(1, 9):
|
||||
result, removed = await b.receive_block(
|
||||
blocks[i], blocks[i - 1].header_block
|
||||
@@ -292,12 +291,10 @@ class TestBlockValidation:
|
||||
# Make it 5x faster than target time
|
||||
blocks = bt.get_consecutive_blocks(test_constants, num_blocks, [], 2)
|
||||
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
for i in range(1, num_blocks):
|
||||
result, removed = await b.receive_block(
|
||||
blocks[i], blocks[i - 1].header_block
|
||||
@@ -334,12 +331,10 @@ class TestReorgs:
|
||||
@pytest.mark.asyncio
|
||||
async def test_basic_reorg(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 100, [], 9)
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
|
||||
for i in range(1, len(blocks)):
|
||||
await b.receive_block(blocks[i], blocks[i - 1].header_block)
|
||||
@@ -367,11 +362,10 @@ class TestReorgs:
|
||||
@pytest.mark.asyncio
|
||||
async def test_reorg_from_genesis(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 20, [], 9, b"0")
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
for i in range(1, len(blocks)):
|
||||
await b.receive_block(blocks[i], blocks[i - 1].header_block)
|
||||
assert b.get_current_tips()[0].height == 20
|
||||
@@ -418,12 +412,10 @@ class TestReorgs:
|
||||
@pytest.mark.asyncio
|
||||
async def test_lca(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
for i in range(1, len(blocks)):
|
||||
await b.receive_block(blocks[i], blocks[i - 1].header_block)
|
||||
|
||||
@@ -447,12 +439,10 @@ class TestReorgs:
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_header_hashes(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 5, [], 9, b"0")
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
|
||||
for i in range(1, len(blocks)):
|
||||
await b.receive_block(blocks[i], blocks[i - 1].header_block)
|
||||
|
||||
@@ -14,5 +14,3 @@ class TestSimulation:
|
||||
db_id_1 = "1001"
|
||||
db_id_2 = "1002"
|
||||
db_id_3 = "1003"
|
||||
|
||||
|
||||
|
||||
+19
-19
@@ -1,7 +1,7 @@
|
||||
import asyncio
|
||||
from secrets import token_bytes
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict
|
||||
import os
|
||||
import sqlite3
|
||||
import random
|
||||
|
||||
@@ -41,16 +41,16 @@ class TestStore:
|
||||
async def test_basic_store(self):
|
||||
assert sqlite3.threadsafety == 1
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 9, [], 9, b"0")
|
||||
db_filename = "blockchain_test"
|
||||
db_filename_2 = "blockchain_test_2"
|
||||
db_filename_3 = "blockchain_test_3"
|
||||
db_filename = Path("blockchain_test")
|
||||
db_filename_2 = Path("blockchain_test_2")
|
||||
db_filename_3 = Path("blockchain_test_3")
|
||||
|
||||
if os.path.isfile(db_filename):
|
||||
os.remove(db_filename)
|
||||
if os.path.isfile(db_filename_2):
|
||||
os.remove(db_filename_2)
|
||||
if os.path.isfile(db_filename_3):
|
||||
os.remove(db_filename_3)
|
||||
if db_filename.exists():
|
||||
db_filename.unlink()
|
||||
if db_filename_2.exists():
|
||||
db_filename_2.unlink()
|
||||
if db_filename_3.exists():
|
||||
db_filename_3.unlink()
|
||||
|
||||
db = await FullNodeStore.create(db_filename)
|
||||
db_2 = await FullNodeStore.create(db_filename_2)
|
||||
@@ -146,8 +146,8 @@ class TestStore:
|
||||
except Exception:
|
||||
await db.close()
|
||||
await db_2.close()
|
||||
os.remove(db_filename)
|
||||
os.remove(db_filename_2)
|
||||
db_filename.unlink()
|
||||
db_filename_2.unlink()
|
||||
raise
|
||||
|
||||
# Different database should have different data
|
||||
@@ -157,17 +157,17 @@ class TestStore:
|
||||
await db.close()
|
||||
await db_2.close()
|
||||
await db_3.close()
|
||||
os.remove(db_filename)
|
||||
os.remove(db_filename_2)
|
||||
os.remove(db_filename_3)
|
||||
db_filename.unlink()
|
||||
db_filename_2.unlink()
|
||||
db_filename_3.unlink()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_deadlock(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 10, [], 9, b"0")
|
||||
db_filename = "blockchain_test"
|
||||
db_filename = Path("blockchain_test")
|
||||
|
||||
if os.path.isfile(db_filename):
|
||||
os.remove(db_filename)
|
||||
if db_filename.exists():
|
||||
db_filename.unlink()
|
||||
|
||||
db = await FullNodeStore.create(db_filename)
|
||||
tasks = []
|
||||
@@ -192,4 +192,4 @@ class TestStore:
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
await db.close()
|
||||
os.remove(db_filename)
|
||||
db_filename.unlink()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import asyncio
|
||||
from typing import Any, Dict
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -36,7 +37,7 @@ class TestUnspent:
|
||||
async def test_basic_unspent_store(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 9, [], 9, b"0")
|
||||
|
||||
db = await UnspentStore.create("fndb_test")
|
||||
db = await UnspentStore.create(Path("fndb_test"))
|
||||
await db._clear_database()
|
||||
|
||||
# Save/get block
|
||||
@@ -53,7 +54,7 @@ class TestUnspent:
|
||||
async def test_set_spent(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 9, [], 9, b"0")
|
||||
|
||||
db = await UnspentStore.create("fndb_test")
|
||||
db = await UnspentStore.create(Path("fndb_test"))
|
||||
await db._clear_database()
|
||||
|
||||
# Save/get block
|
||||
@@ -77,7 +78,7 @@ class TestUnspent:
|
||||
async def test_rollback(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 9, [], 9, b"0")
|
||||
|
||||
db = await UnspentStore.create("fndb_test")
|
||||
db = await UnspentStore.create(Path("fndb_test"))
|
||||
await db._clear_database()
|
||||
|
||||
# Save/get block
|
||||
@@ -113,12 +114,10 @@ class TestUnspent:
|
||||
@pytest.mark.asyncio
|
||||
async def test_basic_reorg(self):
|
||||
blocks = bt.get_consecutive_blocks(test_constants, 100, [], 9)
|
||||
unspent_store = await UnspentStore.create("blockchain_test")
|
||||
store = await FullNodeStore.create("blockchain_test")
|
||||
unspent_store = await UnspentStore.create(Path("blockchain_test"))
|
||||
store = await FullNodeStore.create(Path("blockchain_test"))
|
||||
await store._clear_database()
|
||||
b: Blockchain = await Blockchain.create(
|
||||
{}, unspent_store, store, test_constants
|
||||
)
|
||||
b: Blockchain = await Blockchain.create(unspent_store, store, test_constants)
|
||||
|
||||
for i in range(1, len(blocks)):
|
||||
await b.receive_block(blocks[i], blocks[i - 1].header_block)
|
||||
|
||||
Reference in New Issue
Block a user