Merge #15870: wallet: Only fail rescan when blocks have actually been pruned
fa7e311e16
[doc] rpcwallet: Only fail rescan when blocks have been pruned (MarcoFalke)aaaa57c2aa
scripted-diff: Bump copyright headers in wallet (MarcoFalke)faf3729242
wallet: Only fail rescan when blocks have actually been pruned (MarcoFalke) Pull request description: This brings the behaviour of the import* calls closer to importmulti. After this change, the difference between importmulti and the other import* calls is * that in importmulti you can "opt-out" of scanning early blocks by setting a later timestamp. * that in importmulti the wallet will successfully import the data, but fail to rescan. Whereas in the other calls, the wallet will abort before importing the data. ACKs for commit fa7e31: promag: utACKfa7e311e16
. jnewbery: utACKfa7e311e16
Tree-SHA512: a57d52ffea94b64e0eb9b5d3a7a63031325833908297dd14eb0c5251ffea3b2113b131003f1db4e9599e014369165a57f107a7150bb65e4c791e5fe742f33cb8
This commit is contained in:
commit
d5931f3676
31 changed files with 79 additions and 61 deletions
|
@ -111,6 +111,16 @@ Configuration
|
|||
the selected network. This change takes only effect if the selected network
|
||||
is not mainnet.
|
||||
|
||||
Wallet
|
||||
------
|
||||
|
||||
- When in pruned mode, a rescan that was triggered by an `importwallet`,
|
||||
`importpubkey`, `importaddress`, or `importprivkey` RPC will only fail when
|
||||
blocks have been pruned. Previously it would fail when `-prune` has been set.
|
||||
This change allows to set `-prune` to a high value (e.g. the disk size) and
|
||||
the calls to any of the import RPCs would fail when the first block is
|
||||
pruned.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
|
@ -332,7 +332,11 @@ public:
|
|||
CFeeRate relayMinFee() override { return ::minRelayTxFee; }
|
||||
CFeeRate relayIncrementalFee() override { return ::incrementalRelayFee; }
|
||||
CFeeRate relayDustFee() override { return ::dustRelayFee; }
|
||||
bool getPruneMode() override { return ::fPruneMode; }
|
||||
bool havePruned() override
|
||||
{
|
||||
LOCK(cs_main);
|
||||
return ::fHavePruned;
|
||||
}
|
||||
bool p2pEnabled() override { return g_connman != nullptr; }
|
||||
bool isReadyToBroadcast() override { return !::fImporting && !::fReindex && !IsInitialBlockDownload(); }
|
||||
bool isInitialBlockDownload() override { return IsInitialBlockDownload(); }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
|
@ -196,8 +196,8 @@ public:
|
|||
//! Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's economical to spend.
|
||||
virtual CFeeRate relayDustFee() = 0;
|
||||
|
||||
//! Check if pruning is enabled.
|
||||
virtual bool getPruneMode() = 0;
|
||||
//! Check if any block has been pruned.
|
||||
virtual bool havePruned() = 0;
|
||||
|
||||
//! Check if p2p enabled.
|
||||
virtual bool p2pEnabled() = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2011-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2011-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
@ -158,8 +158,11 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
|||
if (!request.params[2].isNull())
|
||||
fRescan = request.params[2].get_bool();
|
||||
|
||||
if (fRescan && pwallet->chain().getPruneMode()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||
if (fRescan && pwallet->chain().havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will import the key(s),
|
||||
// but fail the rescan with a generic error.
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled when blocks are pruned");
|
||||
}
|
||||
|
||||
if (fRescan && !reserver.reserve()) {
|
||||
|
@ -315,8 +318,11 @@ UniValue importaddress(const JSONRPCRequest& request)
|
|||
if (!request.params[2].isNull())
|
||||
fRescan = request.params[2].get_bool();
|
||||
|
||||
if (fRescan && pwallet->chain().getPruneMode()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||
if (fRescan && pwallet->chain().havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will import the key(s),
|
||||
// but fail the rescan with a generic error.
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled when blocks are pruned");
|
||||
}
|
||||
|
||||
WalletRescanReserver reserver(pwallet);
|
||||
|
@ -508,8 +514,11 @@ UniValue importpubkey(const JSONRPCRequest& request)
|
|||
if (!request.params[2].isNull())
|
||||
fRescan = request.params[2].get_bool();
|
||||
|
||||
if (fRescan && pwallet->chain().getPruneMode()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||
if (fRescan && pwallet->chain().havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will import the key(s),
|
||||
// but fail the rescan with a generic error.
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled when blocks are pruned");
|
||||
}
|
||||
|
||||
WalletRescanReserver reserver(pwallet);
|
||||
|
@ -574,8 +583,11 @@ UniValue importwallet(const JSONRPCRequest& request)
|
|||
},
|
||||
}.ToString());
|
||||
|
||||
if (pwallet->chain().getPruneMode()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode");
|
||||
if (pwallet->chain().havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will import the key(s),
|
||||
// but fail the rescan with a generic error.
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled when blocks are pruned");
|
||||
}
|
||||
|
||||
WalletRescanReserver reserver(pwallet);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-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.
|
||||
|
||||
|
|
|
@ -4209,10 +4209,13 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
|
||||
if (tip_height && *tip_height != rescan_height)
|
||||
{
|
||||
//We can't rescan beyond non-pruned blocks, stop and throw an error
|
||||
//this might happen if a user uses an old wallet within a pruned node
|
||||
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
||||
if (chain.getPruneMode()) {
|
||||
// We can't rescan beyond non-pruned blocks, stop and throw an error.
|
||||
// This might happen if a user uses an old wallet within a pruned node
|
||||
// or if they ran -disablewallet for a longer time, then decided to re-enable
|
||||
if (chain.havePruned()) {
|
||||
// Exit early and print an error.
|
||||
// If a block is pruned after this check, we will load the wallet,
|
||||
// but fail the rescan with a generic error.
|
||||
int block_height = *tip_height;
|
||||
while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
|
||||
--block_height;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2016-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.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2017-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-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.
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ happened previously.
|
|||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_raises_rpc_error,
|
||||
connect_nodes,
|
||||
assert_equal,
|
||||
set_node_times,
|
||||
|
@ -39,23 +38,17 @@ Rescan = enum.Enum("Rescan", "no yes late_timestamp")
|
|||
class Variant(collections.namedtuple("Variant", "call data rescan prune")):
|
||||
"""Helper for importing one key and verifying scanned transactions."""
|
||||
|
||||
def try_rpc(self, func, *args, **kwargs):
|
||||
if self.expect_disabled:
|
||||
assert_raises_rpc_error(-4, "Rescan is disabled in pruned mode", func, *args, **kwargs)
|
||||
else:
|
||||
return func(*args, **kwargs)
|
||||
|
||||
def do_import(self, timestamp):
|
||||
"""Call one key import RPC."""
|
||||
rescan = self.rescan == Rescan.yes
|
||||
|
||||
if self.call == Call.single:
|
||||
if self.data == Data.address:
|
||||
response = self.try_rpc(self.node.importaddress, address=self.address["address"], label=self.label, rescan=rescan)
|
||||
response = self.node.importaddress(address=self.address["address"], label=self.label, rescan=rescan)
|
||||
elif self.data == Data.pub:
|
||||
response = self.try_rpc(self.node.importpubkey, pubkey=self.address["pubkey"], label=self.label, rescan=rescan)
|
||||
response = self.node.importpubkey(pubkey=self.address["pubkey"], label=self.label, rescan=rescan)
|
||||
elif self.data == Data.priv:
|
||||
response = self.try_rpc(self.node.importprivkey, privkey=self.key, label=self.label, rescan=rescan)
|
||||
response = self.node.importprivkey(privkey=self.key, label=self.label, rescan=rescan)
|
||||
assert_equal(response, None)
|
||||
|
||||
elif self.call in (Call.multiaddress, Call.multiscript):
|
||||
|
@ -172,8 +165,7 @@ class ImportRescanTest(BitcoinTestFramework):
|
|||
# check the results from getbalance and listtransactions.
|
||||
for variant in IMPORT_VARIANTS:
|
||||
self.log.info('Run import for variant {}'.format(variant))
|
||||
variant.expect_disabled = variant.rescan == Rescan.yes and variant.prune and variant.call == Call.single
|
||||
expect_rescan = variant.rescan == Rescan.yes and not variant.expect_disabled
|
||||
expect_rescan = variant.rescan == Rescan.yes
|
||||
variant.node = self.nodes[2 + IMPORT_NODES.index(ImportNode(variant.prune, expect_rescan))]
|
||||
variant.do_import(timestamp)
|
||||
if expect_rescan:
|
||||
|
@ -198,12 +190,9 @@ class ImportRescanTest(BitcoinTestFramework):
|
|||
# Check the latest results from getbalance and listtransactions.
|
||||
for variant in IMPORT_VARIANTS:
|
||||
self.log.info('Run check for variant {}'.format(variant))
|
||||
if not variant.expect_disabled:
|
||||
variant.expected_balance += variant.sent_amount
|
||||
variant.expected_txs += 1
|
||||
variant.check(variant.sent_txid, variant.sent_amount, 1)
|
||||
else:
|
||||
variant.check()
|
||||
variant.expected_balance += variant.sent_amount
|
||||
variant.expected_txs += 1
|
||||
variant.check(variant.sent_txid, variant.sent_amount, 1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
ImportRescanTest().main()
|
||||
|
|
Loading…
Reference in a new issue