mirror of
https://github.com/dogecoin/dogecoin.git
synced 2026-01-31 10:30:52 +00:00
Merge pull request #3084 from chromatic/rescan-from-specific-height-squashed
Add optional height to importprivkey RPC
This commit is contained in:
commit
4850eccec4
@ -1,17 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2014-2016 The Bitcoin Core developers
|
||||
# Copyright (c) 2022 The Dogecoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test rescan behavior of importaddress, importpubkey, importprivkey, and
|
||||
importmulti RPCs with different types of keys and rescan options.
|
||||
|
||||
In the first part of the test, node 1 creates an address for each type of
|
||||
import RPC call and node 0 sends BTC to it. Then other nodes import the
|
||||
import RPC call and node 0 sends Doge to it. Then other nodes import the
|
||||
addresses, and the test makes listtransactions and getbalance calls to confirm
|
||||
that the importing node either did or did not execute rescans picking up the
|
||||
send transactions.
|
||||
|
||||
In the second part of the test, node 0 sends more BTC to each address, and the
|
||||
In the second part of the test, node 0 sends more Doge to each address, and the
|
||||
test makes more listtransactions and getbalance calls to confirm that the
|
||||
importing nodes pick up the new transactions regardless of whether rescans
|
||||
happened previously.
|
||||
@ -114,6 +115,9 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
super().__init__()
|
||||
self.num_nodes = 2 + len(IMPORT_NODES)
|
||||
|
||||
def first_node(self):
|
||||
return self.nodes[0]
|
||||
|
||||
def setup_network(self):
|
||||
extra_args = [["-debug=1"] for _ in range(self.num_nodes)]
|
||||
for i, import_node in enumerate(IMPORT_NODES, 2):
|
||||
@ -125,8 +129,11 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
connect_nodes(self.nodes[i], 0)
|
||||
|
||||
def run_test(self):
|
||||
self.test_argument_validation()
|
||||
|
||||
# Create one transaction on node 0 with a unique amount and label for
|
||||
# each possible type of wallet import RPC.
|
||||
|
||||
for i, variant in enumerate(IMPORT_VARIANTS):
|
||||
variant.label = "label {} {}".format(i, variant)
|
||||
variant.address = self.nodes[1].validateaddress(self.nodes[1].getnewaddress(variant.label))
|
||||
@ -179,6 +186,21 @@ class ImportRescanTest(BitcoinTestFramework):
|
||||
else:
|
||||
variant.check()
|
||||
|
||||
def test_argument_validation(self):
|
||||
node = self.first_node()
|
||||
|
||||
try:
|
||||
node.importprivkey("")
|
||||
except JSONRPCException as e:
|
||||
assert("Invalid private key encoding" in e.error["message"])
|
||||
|
||||
address = node.validateaddress(node.getnewaddress("some label"))
|
||||
privkey = node.dumpprivkey(address["address"])
|
||||
|
||||
try:
|
||||
node.importprivkey(privkey, "", True, str(node.getblockcount() + 1))
|
||||
except JSONRPCException as e:
|
||||
assert("Block height out of range" in e.error["message"])
|
||||
|
||||
def try_rpc(func, *args, **kwargs):
|
||||
try:
|
||||
@ -186,6 +208,5 @@ def try_rpc(func, *args, **kwargs):
|
||||
except JSONRPCException as e:
|
||||
return None, e.error
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ImportRescanTest().main()
|
||||
|
||||
@ -103,6 +103,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
||||
{ "lockunspent", 0, "unlock" },
|
||||
{ "lockunspent", 1, "transactions" },
|
||||
{ "importprivkey", 2, "rescan" },
|
||||
{ "importprivkey", 3, "height" },
|
||||
{ "importaddress", 2, "rescan" },
|
||||
{ "importaddress", 3, "p2sh" },
|
||||
{ "importpubkey", 2, "rescan" },
|
||||
|
||||
@ -83,8 +83,8 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(request.fHelp))
|
||||
return NullUniValue;
|
||||
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
|
||||
|
||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
|
||||
throw runtime_error(
|
||||
"importprivkey \"dogecoinprivkey\" ( \"label\" ) ( rescan )\n"
|
||||
"\nAdds a private key (as returned by dumpprivkey) to your wallet.\n"
|
||||
@ -92,6 +92,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
||||
"1. \"dogecoinprivkey\" (string, required) The private key (see dumpprivkey)\n"
|
||||
"2. \"label\" (string, optional, default=\"\") An optional label\n"
|
||||
"3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n"
|
||||
"4. height (numeric, optional, default=1) If rescanning, the block height from which to start\n"
|
||||
"\nNote: This call can take minutes to complete if rescan is true.\n"
|
||||
"\nExamples:\n"
|
||||
"\nDump a private key\n"
|
||||
@ -102,6 +103,8 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
||||
+ HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") +
|
||||
"\nImport using default blank label and without rescan\n"
|
||||
+ HelpExampleCli("importprivkey", "\"mykey\" \"\" false") +
|
||||
"\nImport using default blank label, with rescan, from a specific block height\n"
|
||||
+ HelpExampleCli("importprivkey", "\"mykey\" \"\" true 3760036") +
|
||||
"\nAs a JSON-RPC call\n"
|
||||
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
|
||||
);
|
||||
@ -148,11 +151,23 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
||||
if (!pwalletMain->AddKeyPubKey(key, pubkey))
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||
|
||||
// whenever a key is imported, we need to scan the whole chain
|
||||
pwalletMain->UpdateTimeFirstKey(1);
|
||||
|
||||
if (fRescan) {
|
||||
pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
|
||||
CBlockIndex* pblockindex = chainActive.Genesis();
|
||||
|
||||
if (request.params.size() > 3) {
|
||||
int nHeight = request.params[3].get_int();
|
||||
|
||||
if (nHeight < 0 || nHeight > chainActive.Height())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
|
||||
|
||||
pblockindex = chainActive[nHeight];
|
||||
} else {
|
||||
// we have no implicit first height for a key, so we need to scan the whole chain
|
||||
pwalletMain->UpdateTimeFirstKey(1);
|
||||
}
|
||||
|
||||
pwalletMain->ScanForWalletTransactions(pblockindex, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3244,7 +3244,7 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, {} },
|
||||
{ "wallet", "getwalletinfo", &getwalletinfo, false, {} },
|
||||
{ "wallet", "importmulti", &importmulti, true, {"requests","options"} },
|
||||
{ "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan"} },
|
||||
{ "wallet", "importprivkey", &importprivkey, true, {"privkey","label","rescan", "height"} },
|
||||
{ "wallet", "importwallet", &importwallet, true, {"filename"} },
|
||||
{ "wallet", "importaddress", &importaddress, true, {"address","label","rescan","p2sh"} },
|
||||
{ "wallet", "importprunedfunds", &importprunedfunds, true, {"rawtransaction","txoutproof"} },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user