Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115823
D6511.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
D6511.diff
View Options
diff --git a/src/validation.cpp b/src/validation.cpp
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2085,7 +2085,7 @@
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock &block = *pblock;
if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) {
- return AbortNode(state, "Failed to read block");
+ return error("DisconnectTip(): Failed to read block");
}
// Apply the block atomically to the chain state.
@@ -2630,6 +2630,12 @@
// This is likely a fatal error, but keep the mempool consistent,
// just in case. Only remove from the mempool in this case.
disconnectpool.updateMempoolForReorg(config, false);
+
+ // If we're unable to disconnect a block during normal operation,
+ // then that is a failure of our local system -- we should abort
+ // rather than stay on a less work chain.
+ AbortNode(state,
+ "Failed to disconnect block; see debug.log for details");
return false;
}
diff --git a/test/functional/feature_abortnode.py b/test/functional/feature_abortnode.py
new file mode 100755
--- /dev/null
+++ b/test/functional/feature_abortnode.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# Copyright (c) 2019 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test bitcoind aborts if can't disconnect a block.
+
+- Start a single node and generate 3 blocks.
+- Delete the undo data.
+- Mine a fork that requires disconnecting the tip.
+- Verify that bitcoind AbortNode's.
+"""
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import wait_until, get_datadir_path, connect_nodes
+import os
+
+
+class AbortNodeTest(BitcoinTestFramework):
+
+ def set_test_params(self):
+ self.setup_clean_chain = True
+ self.num_nodes = 2
+ self.extra_args = [["-noparkdeepreorg"], []]
+
+ def setup_network(self):
+ self.setup_nodes()
+ # We'll connect the nodes later
+
+ def run_test(self):
+ self.nodes[0].generate(3)
+ datadir = get_datadir_path(self.options.tmpdir, 0)
+
+ # Deleting the undo file will result in reorg failure
+ os.unlink(os.path.join(datadir, 'regtest', 'blocks', 'rev00000.dat'))
+
+ # Connecting to a node with a more work chain will trigger a reorg
+ # attempt.
+ self.nodes[1].generate(3)
+ with self.nodes[0].assert_debug_log(["Failed to disconnect block"]):
+ connect_nodes(self.nodes[0], self.nodes[1])
+ self.nodes[1].generate(1)
+
+ # Check that node0 aborted
+ self.log.info("Waiting for crash")
+ wait_until(lambda: self.nodes[0].is_node_stopped(), timeout=60)
+ self.log.info("Node crashed - now verifying restart fails")
+ self.nodes[0].assert_start_raises_init_error()
+
+
+if __name__ == '__main__':
+ AbortNodeTest().main()
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 12:11 (44 m, 42 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187800
Default Alt Text
D6511.diff (3 KB)
Attached To
D6511: [backport#15305] [validation] Crash if disconnecting a block fails
Event Timeline
Log In to Comment