mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2026-08-29 18:14:26 -05:00
* Moved keyring handling into a KeyringWrapper class * Update click to 8.0.x for prompt_required support * Renamed KeyringWrapper to _KeyringWrapper * Expose password management options on Linux * CLI support for setting/removing a password * Global option for specifying the master password * Cache the password instead of setting on the context * Password bootstrapping during chia init * Tidying up _KeyringWraper's interface * Initial pass migrating the legacy keyring contents * Encryption/decryption of keyring.yaml contents * FileKeyring backend encrypts with ChaCha20Poly1305 * Tightened up keyring migration and initialization * Fixed issues identified by linters * Remove root_path from Keychain * Prevent double-migration if setting master passwd * KeyringWrapper tests are mostly complete * FileKeyring will now honor the service param * Tests for get/set/delete password * Formatting/commenting updates * Writer lock support with tests - WIP * keyring.yaml is now watched for modifications * Reader/Writer lock for get/delete password * Fixed linter issues * Reader lock tests * Formatting update * Hook up CHIA_ROOT support for KeychainWrapper * Quick fix to address test failures * Fixed failures when existing legacy keyring exists * Fixed test failures caused by reusing the same temp dir * keyring.yaml now lives in ~/.chia_keys by default. Can be overridden with CHIA_KEYS_ROOT or --keys-root-path * Fixed migration failure when setting a password (not using the default) * KeyringWrapper now uses supports_keyring_password to determine if a FileKeyring should be used. Patched tests to work regardless of whether supports_keyring_password return False * The daemon now takes a --have-gui option that will prevent calling check_keys() during startup. If the keyring is locked, we want the GUI to prompt for the password. * Added is_keyring_locked RPC call * Added 'unlock_keyring' RPC command * Added KeychainProxy and KeychainServer to handle RPC messages related to keyring operations. WalletNode no longer directly accesses the Keychain class. * Turn on macOS support for testing keyring passwords * Fixed get_key_for_fingerprint to use the ocal keychain if the platform doesn't need to remotely access the daemon's keychain. Fixed key reconstruction when sent over RPC. * Farmer now accesses the keychain over RPC * Fixes for linter issues and some restructuring to support tests that use setup_nodes.py * Couple of fixes to unblock the GUI from launching when a keyring password is set * Added a keychain RPC call for add_private_key() * Added remaining keychain proxy RPC calls for delete_key_by_fingerprint and delete_all_keys * Check for None when inspecting request arguments * Run check_keys after unlocking the keyring when the daemon is launched via GUI * Added check_keys RPC method. Fixed deserialization of key entropy in get_all_private_keys. This was preventing the GUI from being able to show key details. * Added get_first_private_key to keychain_server/proxy. create_plots now uses the keychain proxy when launched from the daemon. * Added a comment about KeychainProxy in chia plots check * Workaround import conflict when importing from 'tests.*' due to fasteners name conflict * Simulator now uses KeychainProxy if launched by the daemon. KeychainServer/Proxy now takes keychain user/testing params for testing scenarios. * Added "set_keyring_passphrase" RPC message * Reworking KeychainProxy usage to handle local keychain tests and RPC keychain tests. * Replace my prior usage of asyncio.run() with asyncio.get_event_loop().run_until_complete() * Silencing file_keyring logging for the moment. * Updated tests to use test keychains and appropriate BlockTools construction BlockTools should now be created with create_block_tools(_async) to handle async scenarios. Updated block_tools to be async compatible Updated fasteners to fix installation of top-level 'tests' in site-packages * Added 'remove_keyring_passphrase' RPC message to the daemon Minor tweak to TempKeyring to default to some test params * Fixed linter issues * Remove flake8 ignore statement now that the fasteners module has been updated * Some initial renaming changes: password -> passphrase * Fixed wallet RPC issue where get_key_for_fingerprint wasn't awaited-upon. Fixed legacy keyring initialization (for migration scenarios) * Fixed improperly merged file * Fixed linter issues. More renaming. * Updated spots that were still using an incorrect keychain call * Renamed use_password_cache, obtain_current_password * Renamed supports_keyring_password * Renamed has_master_password * Renamed has_cached_password, get_cached_master_password * Linter fixes * Renamed master_password_is_valid * Renamed set_cached_master_password * Renamed set_master_password * Renamed remove_master_password * Renamed has_cached_master_password * Renaming in file_keyring and keyring_wrapper Updated default keyring payload used for tests * Renamed get_password Other renaming updates * Renamed set_password Other renaming updates * Renamed remaining password occurrences (where appropriate) * password -> passphrase * Added tests for setting an emoji and Japanese master passphrase * Attempt to notify the daemon when a keyring passphrase is set/updated/removed * Missed one password -> passphrase replacement. * Fixed some file synchronization issues found when running tests on macOS * Adjusted timeout values for test_writer_lock_reacquisition_failure for macOS. * Removed logging statements previously added for debugging * Prompt for keyring passphrase up-front when launching a service. Changed --have-gui flag to --wait-for-unlock * Updated set_keyring_passphrase RPC message to fix optional current_passphrase param when the keyring is using the default passphrase. * Minor test cleanup to deduplicate some code. * Fixed regression when setting a new master passphrase * Minor refactoring and docs/commenting updates * Renaming password -> passphrase went too far. Keyring backends use password terminology for compatibility with third party backends. * Disabling macOS support (previously added for testing only) * Disabling passphrase support in preparation for sending out the PR * Fixed improper merge (vscode didn't save changes during rebase) * Update chia/cmds/init_funcs.py Co-authored-by: Adam Kelly <338792+aqk@users.noreply.github.com> * skip_check_keys -> should_check_keys * Shuffling some imports around to break cycles reported by LGTM * Handle unlocking the daemon if it's already launched and waiting for unlock. * Replaced uses_keychain_proxy decorator in farmer.py. Fixed async usage of get_reward_targets. Linter/reformatting fixes * Replaced uses_keychain_proxy decorator with a clearer method. * Cleanup the temp keyring dir using shutil.rmtree() * Restored self._root_path (had been changed to self.root_path) * Minor cleanup * ensure_keychain_proxy() now throws if connect_to_keychain_and_validate() fails * Plot key resolution now yields a PlotKeys object which can be passed into create_plots. De-indented test_invalid_icc_sub_slot_vdf to keep git blame tidy. * Added 'keyring_status' daemon RPC message to support the GUI * Minor changes relating to PR feedback * Addressed more PR feedback (mostly type annotations) * Commented-out macOS file keyring usage. This can be re-enabled for testing purposes. * Addressed test failures that require multiple keyrings in the same process. Each TempKeyring will now set a custom KeyringWrapper instance. * Fixed logic for communicating user_passphrase_is_set in the keyring_status RPC response. * Updated type annotations and method signature for set_passphrase to expect a string instead of bytes. * Fixed Wallet RPC tests * Fixed full_node_store tests. BlockTools should be created using the create_block_tools(_async) function(s) * Fixed test failures in test_pool_rpc * Fixed test_daemon. After BlockTools.setup_plots is run, the config file needs to be re-read to refresh stale plot_directories. * Suppressing LGTM false positives regarding passphrase leakage in CLI error output. Seems that LGTM sees MIN_PASSPHRASE_LEN as sensitive data. * Second attempt at suppressing LGTM false positives * Third attempt at addressing LGTM false positives * Removed test_keyring_wrapper param from Keychain ctor. Test setup now sets the keyring_wrapper property directly. * Reformatting * More targeted update of the test config to refresh just the "plot_directories" value * More LGTM suppressions Co-authored-by: Adam Kelly <338792+aqk@users.noreply.github.com> Co-authored-by: wjblanke <wjb98672@gmail.com>
528 lines
17 KiB
Python
528 lines
17 KiB
Python
import asyncio
|
|
import atexit
|
|
import signal
|
|
|
|
from secrets import token_bytes
|
|
from typing import Dict, List, Optional
|
|
|
|
from chia.consensus.constants import ConsensusConstants
|
|
from chia.daemon.server import WebSocketServer, create_server_for_daemon, daemon_launch_lock_path, singleton
|
|
from chia.full_node.full_node_api import FullNodeAPI
|
|
from chia.server.start_farmer import service_kwargs_for_farmer
|
|
from chia.server.start_full_node import service_kwargs_for_full_node
|
|
from chia.server.start_harvester import service_kwargs_for_harvester
|
|
from chia.server.start_introducer import service_kwargs_for_introducer
|
|
from chia.server.start_service import Service
|
|
from chia.server.start_timelord import service_kwargs_for_timelord
|
|
from chia.server.start_wallet import service_kwargs_for_wallet
|
|
from chia.simulator.start_simulator import service_kwargs_for_full_node_simulator
|
|
from chia.timelord.timelord_launcher import kill_processes, spawn_process
|
|
from chia.types.peer_info import PeerInfo
|
|
from chia.util.bech32m import encode_puzzle_hash
|
|
from tests.block_tools import create_block_tools, create_block_tools_async, test_constants
|
|
from tests.util.keyring import TempKeyring
|
|
from chia.util.hash import std_hash
|
|
from chia.util.ints import uint16, uint32
|
|
from chia.util.keychain import bytes_to_mnemonic
|
|
from tests.time_out_assert import time_out_assert_custom_interval
|
|
|
|
|
|
def cleanup_keyring(keyring: TempKeyring):
|
|
keyring.cleanup()
|
|
|
|
|
|
temp_keyring = TempKeyring()
|
|
keychain = temp_keyring.get_keychain()
|
|
atexit.register(cleanup_keyring, temp_keyring) # Attempt to cleanup the temp keychain
|
|
bt = create_block_tools(constants=test_constants, keychain=keychain)
|
|
|
|
self_hostname = bt.config["self_hostname"]
|
|
|
|
|
|
def constants_for_dic(dic):
|
|
return test_constants.replace(**dic)
|
|
|
|
|
|
async def _teardown_nodes(node_aiters: List) -> None:
|
|
awaitables = [node_iter.__anext__() for node_iter in node_aiters]
|
|
for sublist_awaitable in asyncio.as_completed(awaitables):
|
|
try:
|
|
await sublist_awaitable
|
|
except StopAsyncIteration:
|
|
pass
|
|
|
|
|
|
async def setup_daemon(btools):
|
|
root_path = btools.root_path
|
|
config = btools.config
|
|
lockfile = singleton(daemon_launch_lock_path(root_path))
|
|
crt_path = root_path / config["daemon_ssl"]["private_crt"]
|
|
key_path = root_path / config["daemon_ssl"]["private_key"]
|
|
ca_crt_path = root_path / config["private_ssl_ca"]["crt"]
|
|
ca_key_path = root_path / config["private_ssl_ca"]["key"]
|
|
assert lockfile is not None
|
|
create_server_for_daemon(btools.root_path)
|
|
ws_server = WebSocketServer(root_path, ca_crt_path, ca_key_path, crt_path, key_path)
|
|
await ws_server.start()
|
|
|
|
yield ws_server
|
|
|
|
await ws_server.stop()
|
|
|
|
|
|
async def setup_full_node(
|
|
consensus_constants: ConsensusConstants,
|
|
db_name,
|
|
port,
|
|
local_bt,
|
|
introducer_port=None,
|
|
simulator=False,
|
|
send_uncompact_interval=0,
|
|
sanitize_weight_proof_only=False,
|
|
connect_to_daemon=False,
|
|
):
|
|
db_path = local_bt.root_path / f"{db_name}"
|
|
if db_path.exists():
|
|
db_path.unlink()
|
|
config = local_bt.config["full_node"]
|
|
config["database_path"] = db_name
|
|
config["send_uncompact_interval"] = send_uncompact_interval
|
|
config["target_uncompact_proofs"] = 30
|
|
config["peer_connect_interval"] = 50
|
|
config["sanitize_weight_proof_only"] = sanitize_weight_proof_only
|
|
if introducer_port is not None:
|
|
config["introducer_peer"]["host"] = self_hostname
|
|
config["introducer_peer"]["port"] = introducer_port
|
|
else:
|
|
config["introducer_peer"] = None
|
|
config["dns_servers"] = []
|
|
config["port"] = port
|
|
config["rpc_port"] = port + 1000
|
|
overrides = config["network_overrides"]["constants"][config["selected_network"]]
|
|
updated_constants = consensus_constants.replace_str_to_bytes(**overrides)
|
|
if simulator:
|
|
kwargs = service_kwargs_for_full_node_simulator(local_bt.root_path, config, local_bt)
|
|
else:
|
|
kwargs = service_kwargs_for_full_node(local_bt.root_path, config, updated_constants)
|
|
|
|
kwargs.update(
|
|
parse_cli_args=False,
|
|
connect_to_daemon=connect_to_daemon,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start()
|
|
|
|
yield service._api
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
if db_path.exists():
|
|
db_path.unlink()
|
|
|
|
|
|
async def setup_wallet_node(
|
|
port,
|
|
consensus_constants: ConsensusConstants,
|
|
local_bt,
|
|
full_node_port=None,
|
|
introducer_port=None,
|
|
key_seed=None,
|
|
starting_height=None,
|
|
):
|
|
with TempKeyring() as keychain:
|
|
config = bt.config["wallet"]
|
|
config["port"] = port
|
|
config["rpc_port"] = port + 1000
|
|
if starting_height is not None:
|
|
config["starting_height"] = starting_height
|
|
config["initial_num_public_keys"] = 5
|
|
|
|
entropy = token_bytes(32)
|
|
if key_seed is None:
|
|
key_seed = entropy
|
|
keychain.add_private_key(bytes_to_mnemonic(key_seed), "")
|
|
first_pk = keychain.get_first_public_key()
|
|
assert first_pk is not None
|
|
db_path_key_suffix = str(first_pk.get_fingerprint())
|
|
db_name = f"test-wallet-db-{port}-KEY.sqlite"
|
|
db_path_replaced: str = db_name.replace("KEY", db_path_key_suffix)
|
|
db_path = bt.root_path / db_path_replaced
|
|
|
|
if db_path.exists():
|
|
db_path.unlink()
|
|
config["database_path"] = str(db_name)
|
|
config["testing"] = True
|
|
|
|
config["introducer_peer"]["host"] = self_hostname
|
|
if introducer_port is not None:
|
|
config["introducer_peer"]["port"] = introducer_port
|
|
config["peer_connect_interval"] = 10
|
|
else:
|
|
config["introducer_peer"] = None
|
|
|
|
if full_node_port is not None:
|
|
config["full_node_peer"] = {}
|
|
config["full_node_peer"]["host"] = self_hostname
|
|
config["full_node_peer"]["port"] = full_node_port
|
|
else:
|
|
del config["full_node_peer"]
|
|
|
|
kwargs = service_kwargs_for_wallet(local_bt.root_path, config, consensus_constants, keychain)
|
|
kwargs.update(
|
|
parse_cli_args=False,
|
|
connect_to_daemon=False,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start(new_wallet=True)
|
|
|
|
yield service._node, service._node.server
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
if db_path.exists():
|
|
db_path.unlink()
|
|
keychain.delete_all_keys()
|
|
|
|
|
|
async def setup_harvester(port, farmer_port, consensus_constants: ConsensusConstants, b_tools):
|
|
kwargs = service_kwargs_for_harvester(b_tools.root_path, b_tools.config["harvester"], consensus_constants)
|
|
kwargs.update(
|
|
server_listen_ports=[port],
|
|
advertised_port=port,
|
|
connect_peers=[PeerInfo(self_hostname, farmer_port)],
|
|
parse_cli_args=False,
|
|
connect_to_daemon=False,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start()
|
|
|
|
yield service._node, service._node.server
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
|
|
|
|
async def setup_farmer(
|
|
port,
|
|
consensus_constants: ConsensusConstants,
|
|
b_tools,
|
|
full_node_port: Optional[uint16] = None,
|
|
):
|
|
config = bt.config["farmer"]
|
|
config_pool = bt.config["pool"]
|
|
|
|
config["xch_target_address"] = encode_puzzle_hash(b_tools.farmer_ph, "xch")
|
|
config["pool_public_keys"] = [bytes(pk).hex() for pk in b_tools.pool_pubkeys]
|
|
config["port"] = port
|
|
config_pool["xch_target_address"] = encode_puzzle_hash(b_tools.pool_ph, "xch")
|
|
|
|
if full_node_port:
|
|
config["full_node_peer"]["host"] = self_hostname
|
|
config["full_node_peer"]["port"] = full_node_port
|
|
else:
|
|
del config["full_node_peer"]
|
|
|
|
kwargs = service_kwargs_for_farmer(
|
|
b_tools.root_path, config, config_pool, consensus_constants, b_tools.local_keychain
|
|
)
|
|
kwargs.update(
|
|
parse_cli_args=False,
|
|
connect_to_daemon=False,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start()
|
|
|
|
yield service._api, service._node.server
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
|
|
|
|
async def setup_introducer(port):
|
|
kwargs = service_kwargs_for_introducer(
|
|
bt.root_path,
|
|
bt.config["introducer"],
|
|
)
|
|
kwargs.update(
|
|
advertised_port=port,
|
|
parse_cli_args=False,
|
|
connect_to_daemon=False,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start()
|
|
|
|
yield service._api, service._node.server
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
|
|
|
|
async def setup_vdf_client(port):
|
|
vdf_task_1 = asyncio.create_task(spawn_process(self_hostname, port, 1))
|
|
|
|
def stop():
|
|
asyncio.create_task(kill_processes())
|
|
|
|
asyncio.get_running_loop().add_signal_handler(signal.SIGTERM, stop)
|
|
asyncio.get_running_loop().add_signal_handler(signal.SIGINT, stop)
|
|
|
|
yield vdf_task_1
|
|
await kill_processes()
|
|
|
|
|
|
async def setup_vdf_clients(port):
|
|
vdf_task_1 = asyncio.create_task(spawn_process(self_hostname, port, 1))
|
|
vdf_task_2 = asyncio.create_task(spawn_process(self_hostname, port, 2))
|
|
vdf_task_3 = asyncio.create_task(spawn_process(self_hostname, port, 3))
|
|
|
|
def stop():
|
|
asyncio.create_task(kill_processes())
|
|
|
|
asyncio.get_running_loop().add_signal_handler(signal.SIGTERM, stop)
|
|
asyncio.get_running_loop().add_signal_handler(signal.SIGINT, stop)
|
|
|
|
yield vdf_task_1, vdf_task_2, vdf_task_3
|
|
|
|
await kill_processes()
|
|
|
|
|
|
async def setup_timelord(port, full_node_port, sanitizer, consensus_constants: ConsensusConstants, b_tools):
|
|
config = b_tools.config["timelord"]
|
|
config["port"] = port
|
|
config["full_node_peer"]["port"] = full_node_port
|
|
config["sanitizer_mode"] = sanitizer
|
|
config["fast_algorithm"] = False
|
|
if sanitizer:
|
|
config["vdf_server"]["port"] = 7999
|
|
|
|
kwargs = service_kwargs_for_timelord(b_tools.root_path, config, consensus_constants)
|
|
kwargs.update(
|
|
parse_cli_args=False,
|
|
connect_to_daemon=False,
|
|
)
|
|
|
|
service = Service(**kwargs)
|
|
|
|
await service.start()
|
|
|
|
yield service._api, service._node.server
|
|
|
|
service.stop()
|
|
await service.wait_closed()
|
|
|
|
|
|
async def setup_two_nodes(consensus_constants: ConsensusConstants):
|
|
"""
|
|
Setup and teardown of two full nodes, with blockchains and separate DBs.
|
|
"""
|
|
|
|
with TempKeyring() as keychain1, TempKeyring() as keychain2:
|
|
node_iters = [
|
|
setup_full_node(
|
|
consensus_constants,
|
|
"blockchain_test.db",
|
|
21234,
|
|
await create_block_tools_async(constants=test_constants, keychain=keychain1),
|
|
simulator=False,
|
|
),
|
|
setup_full_node(
|
|
consensus_constants,
|
|
"blockchain_test_2.db",
|
|
21235,
|
|
await create_block_tools_async(constants=test_constants, keychain=keychain2),
|
|
simulator=False,
|
|
),
|
|
]
|
|
|
|
fn1 = await node_iters[0].__anext__()
|
|
fn2 = await node_iters[1].__anext__()
|
|
|
|
yield fn1, fn2, fn1.full_node.server, fn2.full_node.server
|
|
|
|
await _teardown_nodes(node_iters)
|
|
|
|
|
|
async def setup_n_nodes(consensus_constants: ConsensusConstants, n: int):
|
|
"""
|
|
Setup and teardown of n full nodes, with blockchains and separate DBs.
|
|
"""
|
|
port_start = 21244
|
|
node_iters = []
|
|
keyrings_to_cleanup = []
|
|
for i in range(n):
|
|
keyring = TempKeyring()
|
|
keyrings_to_cleanup.append(keyring)
|
|
node_iters.append(
|
|
setup_full_node(
|
|
consensus_constants,
|
|
f"blockchain_test_{i}.db",
|
|
port_start + i,
|
|
await create_block_tools_async(constants=test_constants, keychain=keyring.get_keychain()),
|
|
simulator=False,
|
|
)
|
|
)
|
|
nodes = []
|
|
for ni in node_iters:
|
|
nodes.append(await ni.__anext__())
|
|
|
|
yield nodes
|
|
|
|
await _teardown_nodes(node_iters)
|
|
|
|
for keyring in keyrings_to_cleanup:
|
|
keyring.cleanup()
|
|
|
|
|
|
async def setup_node_and_wallet(consensus_constants: ConsensusConstants, starting_height=None, key_seed=None):
|
|
with TempKeyring() as keychain:
|
|
btools = await create_block_tools_async(constants=test_constants, keychain=keychain)
|
|
node_iters = [
|
|
setup_full_node(consensus_constants, "blockchain_test.db", 21234, btools, simulator=False),
|
|
setup_wallet_node(
|
|
21235, consensus_constants, btools, None, starting_height=starting_height, key_seed=key_seed
|
|
),
|
|
]
|
|
|
|
full_node_api = await node_iters[0].__anext__()
|
|
wallet, s2 = await node_iters[1].__anext__()
|
|
|
|
yield full_node_api, wallet, full_node_api.full_node.server, s2
|
|
|
|
await _teardown_nodes(node_iters)
|
|
|
|
|
|
async def setup_simulators_and_wallets(
|
|
simulator_count: int,
|
|
wallet_count: int,
|
|
dic: Dict,
|
|
starting_height=None,
|
|
key_seed=None,
|
|
starting_port=50000,
|
|
):
|
|
with TempKeyring() as keychain1, TempKeyring() as keychain2:
|
|
simulators: List[FullNodeAPI] = []
|
|
wallets = []
|
|
node_iters = []
|
|
|
|
consensus_constants = constants_for_dic(dic)
|
|
for index in range(0, simulator_count):
|
|
port = starting_port + index
|
|
db_name = f"blockchain_test_{port}.db"
|
|
bt_tools = await create_block_tools_async(
|
|
consensus_constants, const_dict=dic, keychain=keychain1
|
|
) # block tools modifies constants
|
|
sim = setup_full_node(
|
|
bt_tools.constants,
|
|
db_name,
|
|
port,
|
|
bt_tools,
|
|
simulator=True,
|
|
)
|
|
simulators.append(await sim.__anext__())
|
|
node_iters.append(sim)
|
|
|
|
for index in range(0, wallet_count):
|
|
if key_seed is None:
|
|
seed = std_hash(uint32(index))
|
|
else:
|
|
seed = key_seed
|
|
port = starting_port + 5000 + index
|
|
bt_tools = await create_block_tools_async(
|
|
consensus_constants, const_dict=dic, keychain=keychain2
|
|
) # block tools modifies constants
|
|
wlt = setup_wallet_node(
|
|
port,
|
|
bt_tools.constants,
|
|
bt_tools,
|
|
None,
|
|
key_seed=seed,
|
|
starting_height=starting_height,
|
|
)
|
|
wallets.append(await wlt.__anext__())
|
|
node_iters.append(wlt)
|
|
|
|
yield simulators, wallets
|
|
|
|
await _teardown_nodes(node_iters)
|
|
|
|
|
|
async def setup_farmer_harvester(consensus_constants: ConsensusConstants):
|
|
node_iters = [
|
|
setup_harvester(21234, 21235, consensus_constants, bt),
|
|
setup_farmer(21235, consensus_constants, bt),
|
|
]
|
|
|
|
harvester, harvester_server = await node_iters[0].__anext__()
|
|
farmer, farmer_server = await node_iters[1].__anext__()
|
|
|
|
yield harvester, farmer
|
|
|
|
await _teardown_nodes(node_iters)
|
|
|
|
|
|
async def setup_full_system(
|
|
consensus_constants: ConsensusConstants, b_tools=None, b_tools_1=None, connect_to_daemon=False
|
|
):
|
|
with TempKeyring() as keychain1, TempKeyring() as keychain2:
|
|
if b_tools is None:
|
|
b_tools = await create_block_tools_async(constants=test_constants, keychain=keychain1)
|
|
if b_tools_1 is None:
|
|
b_tools_1 = await create_block_tools_async(constants=test_constants, keychain=keychain2)
|
|
node_iters = [
|
|
setup_introducer(21233),
|
|
setup_harvester(21234, 21235, consensus_constants, b_tools),
|
|
setup_farmer(21235, consensus_constants, b_tools, uint16(21237)),
|
|
setup_vdf_clients(8000),
|
|
setup_timelord(21236, 21237, False, consensus_constants, b_tools),
|
|
setup_full_node(
|
|
consensus_constants, "blockchain_test.db", 21237, b_tools, 21233, False, 10, True, connect_to_daemon
|
|
),
|
|
setup_full_node(
|
|
consensus_constants, "blockchain_test_2.db", 21238, b_tools_1, 21233, False, 10, True, connect_to_daemon
|
|
),
|
|
setup_vdf_client(7999),
|
|
setup_timelord(21239, 21238, True, consensus_constants, b_tools_1),
|
|
]
|
|
|
|
introducer, introducer_server = await node_iters[0].__anext__()
|
|
harvester, harvester_server = await node_iters[1].__anext__()
|
|
farmer, farmer_server = await node_iters[2].__anext__()
|
|
|
|
async def num_connections():
|
|
count = len(harvester.server.all_connections.items())
|
|
return count
|
|
|
|
await time_out_assert_custom_interval(10, 3, num_connections, 1)
|
|
|
|
vdf_clients = await node_iters[3].__anext__()
|
|
timelord, timelord_server = await node_iters[4].__anext__()
|
|
node_api_1 = await node_iters[5].__anext__()
|
|
node_api_2 = await node_iters[6].__anext__()
|
|
vdf_sanitizer = await node_iters[7].__anext__()
|
|
sanitizer, sanitizer_server = await node_iters[8].__anext__()
|
|
|
|
yield (
|
|
node_api_1,
|
|
node_api_2,
|
|
harvester,
|
|
farmer,
|
|
introducer,
|
|
timelord,
|
|
vdf_clients,
|
|
vdf_sanitizer,
|
|
sanitizer,
|
|
node_api_1.full_node.server,
|
|
)
|
|
|
|
await _teardown_nodes(node_iters)
|