Merge #18671: wallet: Add BlockUntilSyncedToCurrentChain to dumpwallet

fa60afc4fb wallet: Add BlockUntilSyncedToCurrentChain to dumpwallet (MarcoFalke)

Pull request description:

  dumpwallet includes the block hash in the output, so this method depends on the chainstate. According to the developer notes e84a5f0004/doc/developer-notes.md (L1095) it must include a `BlockUntilSyncedToCurrentChain`.

  This is a minor fix and does not need backport, I think.

  It fixes test failures such as https://travis-ci.org/github/bitcoin/bitcoin/jobs/675487097#L2657 , which can only happen in master because the test was not backported.

ACKs for top commit:
  promag:
    Code review ACK fa60afc4fb.
  ryanofsky:
    Code review ACK fa60afc4fb
  meshcollider:
    utACK fa60afc4fb

Tree-SHA512: 8df70b06b226b2cdf880dec9264adb72d66fd81b09b404fd1665a79e5f5236d26122eebf15df00fe71ee292b5c91b2dc23a0a42b2aa50a8d690604b23832723f
This commit is contained in:
Samuel Dobson
2020-04-23 13:57:16 +12:00
2 changed files with 22 additions and 15 deletions

View File

@@ -724,9 +724,8 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
UniValue dumpwallet(const JSONRPCRequest& request) UniValue dumpwallet(const JSONRPCRequest& request)
{ {
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
const CWallet* const pwallet = wallet.get(); if (!EnsureWalletIsAvailable(pwallet.get(), request.fHelp)) {
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue; return NullUniValue;
} }
@@ -750,12 +749,17 @@ UniValue dumpwallet(const JSONRPCRequest& request)
}, },
}.Check(request); }.Check(request);
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*wallet); CWallet& wallet = *pwallet;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(wallet);
// Make sure the results are valid at least up to the most recent block
// the user could have gotten from another RPC command prior to now
wallet.BlockUntilSyncedToCurrentChain();
auto locked_chain = pwallet->chain().lock(); auto locked_chain = pwallet->chain().lock();
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
EnsureWalletIsUnlocked(pwallet); EnsureWalletIsUnlocked(&wallet);
fs::path filepath = request.params[0].get_str(); fs::path filepath = request.params[0].get_str();
filepath = fs::absolute(filepath); filepath = fs::absolute(filepath);
@@ -791,9 +795,9 @@ UniValue dumpwallet(const JSONRPCRequest& request)
// produce output // produce output
file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD); file << strprintf("# Wallet dump created by Bitcoin %s\n", CLIENT_BUILD);
file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime())); file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime()));
file << strprintf("# * Best block at time of backup was %i (%s),\n", pwallet->GetLastBlockHeight(), pwallet->GetLastBlockHash().ToString()); file << strprintf("# * Best block at time of backup was %i (%s),\n", wallet.GetLastBlockHeight(), wallet.GetLastBlockHash().ToString());
int64_t block_time = 0; int64_t block_time = 0;
CHECK_NONFATAL(pwallet->chain().findBlock(pwallet->GetLastBlockHash(), FoundBlock().time(block_time))); CHECK_NONFATAL(wallet.chain().findBlock(wallet.GetLastBlockHash(), FoundBlock().time(block_time)));
file << strprintf("# mined on %s\n", FormatISO8601DateTime(block_time)); file << strprintf("# mined on %s\n", FormatISO8601DateTime(block_time));
file << "\n"; file << "\n";
@@ -817,8 +821,8 @@ UniValue dumpwallet(const JSONRPCRequest& request)
CKey key; CKey key;
if (spk_man.GetKey(keyid, key)) { if (spk_man.GetKey(keyid, key)) {
file << strprintf("%s %s ", EncodeSecret(key), strTime); file << strprintf("%s %s ", EncodeSecret(key), strTime);
if (GetWalletAddressesForKey(&spk_man, pwallet, keyid, strAddr, strLabel)) { if (GetWalletAddressesForKey(&spk_man, &wallet, keyid, strAddr, strLabel)) {
file << strprintf("label=%s", strLabel); file << strprintf("label=%s", strLabel);
} else if (keyid == seed_id) { } else if (keyid == seed_id) {
file << "hdseed=1"; file << "hdseed=1";
} else if (mapKeyPool.count(keyid)) { } else if (mapKeyPool.count(keyid)) {

View File

@@ -217,16 +217,19 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
// Import key into wallet and call dumpwallet to create backup file. // Import key into wallet and call dumpwallet to create backup file.
{ {
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(chain.get(), WalletLocation(), WalletDatabase::CreateDummy()); std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(chain.get(), WalletLocation(), WalletDatabase::CreateDummy());
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan(); {
LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore); auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME; LOCK2(wallet->cs_wallet, spk_man->cs_KeyStore);
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); spk_man->mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
spk_man->AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
}
JSONRPCRequest request; JSONRPCRequest request;
request.params.setArray(); request.params.setArray();
request.params.push_back(backup_file); request.params.push_back(backup_file);
AddWallet(wallet);
wallet->SetLastBlockProcessed(::ChainActive().Height(), ::ChainActive().Tip()->GetBlockHash());
::dumpwallet(request); ::dumpwallet(request);
RemoveWallet(wallet); RemoveWallet(wallet);
} }