Repository: bitcoin/bitcoin
File: test/functional/test_framework/test_node.py (Python)

Code before:
            stdout = tempfile.NamedTemporaryFile(dir=self.stdout_dir, delete=False)
        self.stderr = stderr
        self.stdout = stdout

        if cwd is None:
            cwd = self.cwd

        # Delete any existing cookie file -- if such a file exists (eg due to
        # unclean shutdown), it will get overwritten anyway by bitcoind, and
        # potentially interfere with our attempt to authenticate
        delete_cookie_file(self.datadir_path, self.chain)

        # add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
        subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
        if env is not None:
            subp_env.update(env)

        self.process = subprocess.Popen(self.args + extra_args, env=subp_env, stdout=stdout, stderr=stderr, cwd=cwd, **kwargs)

        self.running = True
        self.log.debug("bitcoind started, waiting for RPC to come up")

        if self.start_perf:
            self._start_perf()

    def wait_for_rpc_connection(self, wait_for_import=True):
        """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect."""
        # Poll at a rate of four times per second
        poll_per_s = 4
        for _ in range(poll_per_s * self.rpc_timeout):
            if self.process.poll() is not None:
                # Attach abrupt shutdown error/s to the exception message
                self.stderr.seek(0)
                str_error = ''.join(line.decode('utf-8') for line in self.stderr)
                str_error += "************************\n" if str_error else ''

                raise FailedToStartError(self._node_msg(
                    f'bitcoind exited with status {self.process.returncode} during initialization. {str_error}'))
            try:
                rpc = get_rpc_proxy(
                    rpc_url(self.datadir_path, self.index, self.chain, self.rpchost),
                    self.index,
                    timeout=self.rpc_timeout // 2,  # Shorter timeout to allow for one retry in case of ETIMEDOUT
                    coveragedir=self.coverage_dir,
                )
                rpc.getblockcount()
                # If the call to getblockcount() succeeds then the RPC connection is up
                if self.version_is_at_least(190000) and wait_for_import:
                    # getmempoolinfo.loaded is available since commit
                    # bb8ae2c (version 0.19.0)
                    self.wait_until(lambda: rpc.getmempoolinfo()['loaded'])

Review comment (suggestion):
nit: Could force named args for options?
```suggestion
    def wait_for_rpc_connection(self, *, wait_for_import=True):
```

Code after:
            stdout = tempfile.NamedTemporaryFile(dir=self.stdout_dir, delete=False)
        self.stderr = stderr
        self.stdout = stdout

        if cwd is None:
            cwd = self.cwd

        # Delete any existing cookie file -- if such a file exists (eg due to
        # unclean shutdown), it will get overwritten anyway by bitcoind, and
        # potentially interfere with our attempt to authenticate
        delete_cookie_file(self.datadir_path, self.chain)

        # add environment variable LIBC_FATAL_STDERR_=1 so that libc errors are written to stderr and not the terminal
        subp_env = dict(os.environ, LIBC_FATAL_STDERR_="1")
        if env is not None:
            subp_env.update(env)

        self.process = subprocess.Popen(self.args + extra_args, env=subp_env, stdout=stdout, stderr=stderr, cwd=cwd, **kwargs)

        self.running = True
        self.log.debug("bitcoind started, waiting for RPC to come up")

        if self.start_perf:
            self._start_perf()

    def wait_for_rpc_connection(self, *, wait_for_import=True):
        """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect."""
        # Poll at a rate of four times per second
        poll_per_s = 4
        for _ in range(poll_per_s * self.rpc_timeout):
            if self.process.poll() is not None:
                # Attach abrupt shutdown error/s to the exception message
                self.stderr.seek(0)
                str_error = ''.join(line.decode('utf-8') for line in self.stderr)
                str_error += "************************\n" if str_error else ''

                raise FailedToStartError(self._node_msg(
                    f'bitcoind exited with status {self.process.returncode} during initialization. {str_error}'))
            try:
                rpc = get_rpc_proxy(
                    rpc_url(self.datadir_path, self.index, self.chain, self.rpchost),
                    self.index,
                    timeout=self.rpc_timeout // 2,  # Shorter timeout to allow for one retry in case of ETIMEDOUT
                    coveragedir=self.coverage_dir,
                )
                rpc.getblockcount()
                # If the call to getblockcount() succeeds then the RPC connection is up
                if self.version_is_at_least(190000) and wait_for_import:
                    # getmempoolinfo.loaded is available since commit
                    # bb8ae2c (version 0.19.0)
                    self.wait_until(lambda: rpc.getmempoolinfo()['loaded'])