Merge bitcoin/bitcoin#27708: Return EXIT_FAILURE on post-init fatal errors

61c569ab60 refactor: decouple early return commands from AppInit (furszy)
4927167f85 gui: return EXIT_FAILURE on post-init fatal errors (furszy)
3b2c61e819 Return EXIT_FAILURE on post-init fatal errors (furszy)
3c06926cf2 refactor: index: use `AbortNode` in fatal error helper (Sebastian Falbesoner)
9ddf7e03a3 move ThreadImport ABC error to use AbortNode (furszy)

Pull request description:

  It seems odd to return `EXIT_SUCCESS` when the node aborted execution due a fatal internal error
  or any post-init problem that triggers an unrequested shutdown.

  e.g. blocks or coins db I/O errors, disconnect block failure, failure during thread import (external
  blocks loading process error), among others.

ACKs for top commit:
  TheCharlatan:
    ACK 61c569ab60
  ryanofsky:
    Code review ACK 61c569ab60
  pinheadmz:
    ACK 61c569ab60
  theStack:
    Code-review ACK 61c569ab60

Tree-SHA512: 18a59c3acc1c6d12cbc74a20a401e89659740c6477fccb59070c9f97922dfe588468e9e5eef56c5f395762187c34179a5e3954aa5b844787fa13da2e666c63d3
This commit is contained in:
Ryan Ofsky
2023-06-12 12:13:55 -04:00
14 changed files with 85 additions and 56 deletions

View File

@@ -40,7 +40,7 @@ class AbortNodeTest(BitcoinTestFramework):
# Check that node0 aborted
self.log.info("Waiting for crash")
self.nodes[0].wait_until_stopped(timeout=5)
self.nodes[0].wait_until_stopped(timeout=5, expect_error=True)
self.log.info("Node crashed - now verifying restart fails")
self.nodes[0].assert_start_raises_init_error()

View File

@@ -365,7 +365,7 @@ class TestNode():
if wait_until_stopped:
self.wait_until_stopped()
def is_node_stopped(self):
def is_node_stopped(self, expected_ret_code=None):
"""Checks whether the node has stopped.
Returns True if the node has stopped. False otherwise.
@@ -377,8 +377,13 @@ class TestNode():
return False
# process has stopped. Assert that it didn't return an error code.
assert return_code == 0, self._node_msg(
"Node returned non-zero exit code (%d) when stopping" % return_code)
# unless 'expected_ret_code' is provided.
if expected_ret_code is not None:
assert return_code == expected_ret_code, self._node_msg(
"Node returned unexpected exit code (%d) vs (%d) when stopping" % (return_code, expected_ret_code))
else:
assert return_code == 0, self._node_msg(
"Node returned non-zero exit code (%d) when stopping" % return_code)
self.running = False
self.process = None
self.rpc_connected = False
@@ -386,8 +391,9 @@ class TestNode():
self.log.debug("Node stopped")
return True
def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT):
wait_until_helper(self.is_node_stopped, timeout=timeout, timeout_factor=self.timeout_factor)
def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT, expect_error=False):
expected_ret_code = 1 if expect_error else None # Whether node shutdown return EXIT_FAILURE or EXIT_SUCCESS
wait_until_helper(lambda: self.is_node_stopped(expected_ret_code=expected_ret_code), timeout=timeout, timeout_factor=self.timeout_factor)
def replace_in_config(self, replacements):
"""