Repository: Chia-Network/chia-blockchain
File: chia/_tests/util/setup_nodes.py (Python)

Code before:
@asynccontextmanager
async def setup_full_system_inner(
    b_tools: BlockTools | None,
    b_tools_1: BlockTools | None,
    connect_to_daemon: bool,
    consensus_constants: ConsensusConstants,
    db_version: int,
    keychain1: Keychain,
    keychain2: Keychain,
    shared_b_tools: BlockTools,
) -> AsyncIterator[FullSystem]:
    config_overrides = {"full_node.max_sync_wait": 0, "full_node.log_coins": True}

    self_hostname = shared_b_tools.config["self_hostname"]

    async with AsyncExitStack() as async_exit_stack:
        vdf1_port = uint16(find_available_listen_port("vdf1"))
        vdf2_port = uint16(find_available_listen_port("vdf2"))

        if b_tools is None:
            b_tools = await async_exit_stack.enter_async_context(
                create_block_tools_async(
                    constants=consensus_constants, keychain=keychain1, config_overrides=config_overrides
                )
            )
        if b_tools_1 is None:
            b_tools_1 = await async_exit_stack.enter_async_context(
                create_block_tools_async(
                    constants=consensus_constants, keychain=keychain2, config_overrides=config_overrides
                )
            )

        await async_exit_stack.enter_async_context(
            setup_vdf_clients(bt=b_tools, self_hostname=self_hostname, port=vdf1_port)
        )
        await async_exit_stack.enter_async_context(
            setup_vdf_client(bt=shared_b_tools, self_hostname=self_hostname, port=vdf2_port)
        )

        daemon_ws = await async_exit_stack.enter_async_context(setup_daemon(btools=b_tools))

        # Start the introducer first so we can find out the port, and use that for the nodes
        introducer_service = await async_exit_stack.enter_async_context(setup_introducer(shared_b_tools, uint16(0)))
        introducer = introducer_service._api
        introducer_server = introducer_service._node.server
        introducer.introducer.dns_servers = []

        # Then start the full node so we can use the port for the farmer and timelord
        node_1 = await async_exit_stack.enter_async_context(
            setup_full_node(
                consensus_constants,

Review comment (suggestion):
it's not obvious that it's safe to start these block tools *after* we try to find available local listen ports. They may try to open listen sockets themselves. I think it would be safer to move these up to create them in the original order

Code after:
    b_tools: BlockTools | None,
    b_tools_1: BlockTools | None,
    connect_to_daemon: bool,
    consensus_constants: ConsensusConstants,
    db_version: int,
    keychain1: Keychain,
    keychain2: Keychain,
    shared_b_tools: BlockTools,
) -> AsyncIterator[FullSystem]:
    config_overrides = {"full_node.max_sync_wait": 0, "full_node.log_coins": True}

    self_hostname = shared_b_tools.config["self_hostname"]

    async with AsyncExitStack() as async_exit_stack:
        if b_tools is None:
            b_tools = await async_exit_stack.enter_async_context(
                create_block_tools_async(
                    constants=consensus_constants, keychain=keychain1, config_overrides=config_overrides
                )
            )
        if b_tools_1 is None:
            b_tools_1 = await async_exit_stack.enter_async_context(
                create_block_tools_async(
                    constants=consensus_constants, keychain=keychain2, config_overrides=config_overrides
                )
            )

        vdf1_port = uint16(find_available_listen_port("vdf1"))
        vdf2_port = uint16(find_available_listen_port("vdf2"))

        await async_exit_stack.enter_async_context(
            setup_vdf_clients(bt=b_tools, self_hostname=self_hostname, port=vdf1_port)
        )
        await async_exit_stack.enter_async_context(
            setup_vdf_client(bt=shared_b_tools, self_hostname=self_hostname, port=vdf2_port)
        )

        daemon_ws = await async_exit_stack.enter_async_context(setup_daemon(btools=b_tools))

        # Start the introducer first so we can find out the port, and use that for the nodes
        introducer_service = await async_exit_stack.enter_async_context(setup_introducer(shared_b_tools, uint16(0)))
        introducer = introducer_service._api
        introducer_server = introducer_service._node.server
        introducer.introducer.dns_servers = []

        # Then start the full node so we can use the port for the farmer and timelord
        node_1 = await async_exit_stack.enter_async_context(
            setup_full_node(
                consensus_constants,
                "blockchain_test_1.db",
                self_hostname=self_hostname,