diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 9916fd7f9ea..5a373e4cd95 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -46,6 +46,8 @@ BITCOIND_PROC_WAIT_TIMEOUT = 60 # The size of the blocks xor key # from InitBlocksdirXorKey::xor_key.size() NUM_XOR_BYTES = 8 +CLI_MAX_ARG_SIZE = 131071 # many systems have a 128kb limit per arg (MAX_ARG_STRLEN) + # The null blocks key (all 0s) NULL_BLK_XOR_KEY = bytes([0] * NUM_XOR_BYTES) BITCOIN_PID_FILENAME_DEFAULT = "bitcoind.pid" @@ -920,12 +922,24 @@ class TestNodeCLI(): p_args = self.binaries.rpc_argv() + [f"-datadir={self.datadir}"] + self.options if named_args: p_args += ["-named"] + base_arg_pos = len(p_args) if clicommand is not None: p_args += [clicommand] p_args += pos_args + named_args + max_arg_size = max(len(arg) for arg in p_args) + stdin_data = self.input + if max_arg_size > CLI_MAX_ARG_SIZE: + self.log.debug(f"Cli: Command size {max_arg_size} too large, using stdin") + rpc_args = "\n".join([arg for arg in p_args[base_arg_pos:]]) + if stdin_data is not None: + stdin_data += "\n" + rpc_args + else: + stdin_data = rpc_args + p_args = p_args[:base_arg_pos] + ['-stdin'] + self.log.debug("Running bitcoin-cli {}".format(p_args[2:])) process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - cli_stdout, cli_stderr = process.communicate(input=self.input) + cli_stdout, cli_stderr = process.communicate(input=stdin_data) returncode = process.poll() if returncode: match = re.match(r'error code: ([-0-9]+)\nerror message:\n(.*)', cli_stderr)