Skip to content

Commit 60b86d1

Browse files
fjahrPiRK
authored andcommitted
rpc: Include assumeutxo as a failure reason of rescanblockchain
bitcoin/bitcoin@42d5d53 bitcoin/bitcoin@9d2d9f7
1 parent 3c8fa6c commit 60b86d1

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

src/interfaces/chain.h

+3
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ class Chain {
228228
//! Check if any block has been pruned.
229229
virtual bool havePruned() = 0;
230230

231+
//! Get the current prune height.
232+
virtual std::optional<int> getPruneHeight() = 0;
233+
231234
//! Check if the node is ready to broadcast transactions.
232235
virtual bool isReadyToBroadcast() = 0;
233236

src/node/interfaces.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <policy/settings.h>
2828
#include <primitives/block.h>
2929
#include <primitives/transaction.h>
30+
#include <rpc/blockchain.h>
3031
#include <rpc/protocol.h>
3132
#include <rpc/server.h>
3233
#include <shutdown.h>
@@ -716,6 +717,10 @@ namespace {
716717
return !chainman().m_blockman.LoadingBlocks() &&
717718
!isInitialBlockDownload();
718719
}
720+
std::optional<int> getPruneHeight() override {
721+
LOCK(chainman().GetMutex());
722+
return GetPruneHeight(chainman().m_blockman, chainman().ActiveChain());
723+
}
719724
bool isInitialBlockDownload() override {
720725
return chainman().IsInitialBlockDownload();
721726
}

src/wallet/rpcwallet.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -3767,14 +3767,29 @@ RPCHelpMan rescanblockchain() {
37673767
}
37683768
}
37693769

3770-
// We can't rescan beyond non-pruned blocks, stop and throw an
3771-
// error
3770+
// We can't rescan unavailable blocks, stop and throw an error
37723771
if (!pwallet->chain().hasBlocks(pwallet->GetLastBlockHash(),
37733772
start_height, stop_height)) {
3773+
if (pwallet->chain().havePruned() &&
3774+
pwallet->chain().getPruneHeight() >= start_height) {
3775+
throw JSONRPCError(RPC_MISC_ERROR,
3776+
"Can't rescan beyond pruned data. "
3777+
"Use RPC call getblockchaininfo to "
3778+
"determine your pruned height.");
3779+
}
3780+
if (pwallet->chain().hasAssumedValidChain()) {
3781+
throw JSONRPCError(
3782+
RPC_MISC_ERROR,
3783+
"Failed to rescan unavailable blocks likely due to "
3784+
"an in-progress assumeutxo background sync. Check "
3785+
"logs or getchainstates RPC for assumeutxo "
3786+
"background sync progress and try again later.");
3787+
}
37743788
throw JSONRPCError(
37753789
RPC_MISC_ERROR,
3776-
"Can't rescan beyond pruned data. Use RPC call "
3777-
"getblockchaininfo to determine your pruned height.");
3790+
"Failed to rescan unavailable blocks, potentially "
3791+
"caused by data corruption. If the issue persists you "
3792+
"may want to reindex (see -reindex option).");
37783793
}
37793794

37803795
CHECK_NONFATAL(pwallet->chain().findAncestorByHeight(

test/functional/wallet_assumeutxo.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ def run_test(self):
161161
self.log.info("Backup from before the snapshot height can't be loaded during background sync")
162162
assert_raises_rpc_error(-4, "Wallet loading failed. Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height 299", n1.restorewallet, "w2", "backup_w2.dat")
163163

164+
wallet_name = "w1"
165+
n1.createwallet(wallet_name, disable_private_keys=True)
164166
if self.options.descriptors:
165167
self.log.info("Test loading descriptors during background sync")
166-
wallet_name = "w1"
167-
n1.createwallet(wallet_name, disable_private_keys=True)
168168
key = get_generate_key()
169169
time = n1.getblockchaininfo()['time']
170170
timestamp = 0
@@ -181,6 +181,10 @@ def run_test(self):
181181
assert_equal(result[0]['error']['code'], -1)
182182
assert_equal(result[0]['error']['message'], expected_error_message)
183183

184+
self.log.info("Test that rescanning blocks from before the snapshot fails when blocks are not available from the background sync yet")
185+
w1 = n1.get_wallet_rpc(wallet_name)
186+
assert_raises_rpc_error(-1, "Failed to rescan unavailable blocks likely due to an in-progress assumeutxo background sync. Check logs or getchainstates RPC for assumeutxo background sync progress and try again later.", w1.rescanblockchain, 100)
187+
184188
PAUSE_HEIGHT = FINAL_HEIGHT - 40
185189

186190
self.log.info("Restarting node to stop at height %d", PAUSE_HEIGHT)

0 commit comments

Comments
 (0)