diff options
author | W. J. van der Laan <laanwj@protonmail.com> | 2021-11-10 18:16:50 +0100 |
---|---|---|
committer | W. J. van der Laan <laanwj@protonmail.com> | 2021-11-10 18:55:54 +0100 |
commit | e7feb73f07179653c0a768ce5d96abe983441936 (patch) | |
tree | 521e781bd619f0a1e331863134caf6cdea013113 | |
parent | 4a8707741de2a8646d66b73d88b753fc9f4d9772 (diff) | |
parent | d150fe3ad5ce181511f2d2fd035a10530eaa4203 (diff) |
Merge bitcoin/bitcoin#22805: refactor: use CWallet const shared pointers in dump{privkey,wallet}
d150fe3ad5ce181511f2d2fd035a10530eaa4203 refactor: use `CWallet` const shared pointers in dump{privkey,wallet} RPCs (Sebastian Falbesoner)
ec2792d1dc3404d749a43556eeb4b63780ee6d94 refactor: use const `LegacyScriptPubKeyMan` references in dump{privkey,wallet} RPCs (Sebastian Falbesoner)
29905c092f15bbbc4d4964c2f99dcf12fefd4111 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 d150fe3ad5ce181511f2d2fd035a10530eaa4203
Tree-SHA512: 90ac05e21f40c6d0ebb479a71c545da2fd89940b9ca3409d9f932abc983bf8830d34c45086e68880d0d1e994846fbefee7534eec142ff4268e0fa28a1a411d36
-rw-r--r-- | src/wallet/rpcdump.cpp | 19 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 9 | ||||
-rw-r--r-- | src/wallet/rpcwallet.h | 1 |
3 files changed, 21 insertions, 8 deletions
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 5edd9f8f66..403c978680 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -57,7 +57,7 @@ static std::string DecodeDumpString(const std::string &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; CKey key; @@ -681,10 +681,10 @@ RPCHelpMan dumpprivkey() }, [&](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; - LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); + const LegacyScriptPubKeyMan& spk_man = EnsureConstLegacyScriptPubKeyMan(*pwallet); LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); @@ -731,11 +731,11 @@ RPCHelpMan dumpwallet() }, [&](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; - CWallet& wallet = *pwallet; - LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(wallet); + const CWallet& wallet = *pwallet; + const LegacyScriptPubKeyMan& spk_man = EnsureConstLegacyScriptPubKeyMan(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 @@ -809,6 +809,9 @@ RPCHelpMan dumpwallet() std::string strLabel; CKey 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); if (GetWalletAddressesForKey(&spk_man, wallet, keyid, strAddr, strLabel)) { file << strprintf("label=%s", strLabel); @@ -816,12 +819,12 @@ RPCHelpMan dumpwallet() file << "hdseed=1"; } else if (mapKeyPool.count(keyid)) { file << "reserve=1"; - } else if (spk_man.mapKeyMetadata[keyid].hdKeypath == "s") { + } else if (metadata.hdKeypath == "s") { file << "inactivehdseed=1"; } else { 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"; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 86bfa10d88..babb61b03a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -150,6 +150,15 @@ LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_cr 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) { interfaces::Chain& chain = wallet.chain(); diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 8b88ffe8ed..3a85fc0c64 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -34,6 +34,7 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques void EnsureWalletIsUnlocked(const CWallet&); WalletContext& EnsureWalletContext(const std::any& context); LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false); +const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet); RPCHelpMan getaddressinfo(); RPCHelpMan signrawtransactionwithwallet(); |