0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

Merge bitcoin/bitcoin#22805: refactor: use CWallet const shared pointers in dump{privkey,wallet}

d150fe3ad5 refactor: use `CWallet` const shared pointers in dump{privkey,wallet} RPCs (Sebastian Falbesoner)
ec2792d1dc refactor: use const `LegacyScriptPubKeyMan` references in dump{privkey,wallet} RPCs (Sebastian Falbesoner)
29905c092f refactor: avoid multiple key->metadata lookups in dumpwallet RPC (Sebastian Falbesoner)

Pull request description:

  ~~This PR is based on #22787 ("refactor: actual immutable pointing"), which should be reviewed first.~~ (merged by now)

  It aims to make the CWallet shared pointers actually immutable also for the `dumpprivkey` and `dumpwallet` RPC methods. For doing that, some more preparations are needed; we need a const-counterpart to the helper `EnsureLegacyScriptPubKeyMan` that accepts a const CWallet pointer and accordingly also returns a const `LegacyScriptPubKeyMan` instance. The metadata lookup in `dumpwallet` is changed to not need a mutable `ScriptPubKeyMan` instance by avoiding using the `operator[]` in its mapKeyMetadata map, which also avoids repeated lookups.

ACKs for top commit:
  laanwj:
    Code review ACK d150fe3ad5

Tree-SHA512: 90ac05e21f40c6d0ebb479a71c545da2fd89940b9ca3409d9f932abc983bf8830d34c45086e68880d0d1e994846fbefee7534eec142ff4268e0fa28a1a411d36
This commit is contained in:
W. J. van der Laan 2021-11-10 18:16:50 +01:00
commit e7feb73f07
No known key found for this signature in database
GPG key ID: 1E4AED62986CD25D
3 changed files with 21 additions and 8 deletions

View file

@ -57,7 +57,7 @@ static std::string DecodeDumpString(const std::string &str) {
return ret.str(); return ret.str();
} }
static bool GetWalletAddressesForKey(LegacyScriptPubKeyMan* spk_man, const CWallet& wallet, const CKeyID& keyid, std::string& strAddr, std::string& strLabel) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) static bool GetWalletAddressesForKey(const LegacyScriptPubKeyMan* spk_man, const CWallet& wallet, const CKeyID& keyid, std::string& strAddr, std::string& strLabel) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{ {
bool fLabelFound = false; bool fLabelFound = false;
CKey key; CKey key;
@ -681,10 +681,10 @@ RPCHelpMan dumpprivkey()
}, },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return NullUniValue; if (!pwallet) return NullUniValue;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); const LegacyScriptPubKeyMan& spk_man = EnsureConstLegacyScriptPubKeyMan(*pwallet);
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
@ -731,11 +731,11 @@ RPCHelpMan dumpwallet()
}, },
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return NullUniValue; if (!pwallet) return NullUniValue;
CWallet& wallet = *pwallet; const CWallet& wallet = *pwallet;
LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(wallet); const LegacyScriptPubKeyMan& spk_man = EnsureConstLegacyScriptPubKeyMan(wallet);
// Make sure the results are valid at least up to the most recent block // 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 // the user could have gotten from another RPC command prior to now
@ -809,6 +809,9 @@ RPCHelpMan dumpwallet()
std::string strLabel; std::string strLabel;
CKey key; CKey key;
if (spk_man.GetKey(keyid, key)) { if (spk_man.GetKey(keyid, key)) {
CKeyMetadata metadata;
const auto it{spk_man.mapKeyMetadata.find(keyid)};
if (it != spk_man.mapKeyMetadata.end()) metadata = it->second;
file << strprintf("%s %s ", EncodeSecret(key), strTime); file << strprintf("%s %s ", EncodeSecret(key), strTime);
if (GetWalletAddressesForKey(&spk_man, wallet, keyid, strAddr, strLabel)) { if (GetWalletAddressesForKey(&spk_man, wallet, keyid, strAddr, strLabel)) {
file << strprintf("label=%s", strLabel); file << strprintf("label=%s", strLabel);
@ -816,12 +819,12 @@ RPCHelpMan dumpwallet()
file << "hdseed=1"; file << "hdseed=1";
} else if (mapKeyPool.count(keyid)) { } else if (mapKeyPool.count(keyid)) {
file << "reserve=1"; file << "reserve=1";
} else if (spk_man.mapKeyMetadata[keyid].hdKeypath == "s") { } else if (metadata.hdKeypath == "s") {
file << "inactivehdseed=1"; file << "inactivehdseed=1";
} else { } else {
file << "change=1"; file << "change=1";
} }
file << strprintf(" # addr=%s%s\n", strAddr, (spk_man.mapKeyMetadata[keyid].has_key_origin ? " hdkeypath="+WriteHDKeypath(spk_man.mapKeyMetadata[keyid].key_origin.path) : "")); file << strprintf(" # addr=%s%s\n", strAddr, (metadata.has_key_origin ? " hdkeypath="+WriteHDKeypath(metadata.key_origin.path) : ""));
} }
} }
file << "\n"; file << "\n";

View file

@ -150,6 +150,15 @@ LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_cr
return *spk_man; return *spk_man;
} }
const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet)
{
const LegacyScriptPubKeyMan* spk_man = wallet.GetLegacyScriptPubKeyMan();
if (!spk_man) {
throw JSONRPCError(RPC_WALLET_ERROR, "This type of wallet does not support this command");
}
return *spk_man;
}
static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry) static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry)
{ {
interfaces::Chain& chain = wallet.chain(); interfaces::Chain& chain = wallet.chain();

View file

@ -34,6 +34,7 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques
void EnsureWalletIsUnlocked(const CWallet&); void EnsureWalletIsUnlocked(const CWallet&);
WalletContext& EnsureWalletContext(const std::any& context); WalletContext& EnsureWalletContext(const std::any& context);
LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false); LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet);
RPCHelpMan getaddressinfo(); RPCHelpMan getaddressinfo();
RPCHelpMan signrawtransactionwithwallet(); RPCHelpMan signrawtransactionwithwallet();