77773e8 refactor: In CNode use util::NotNull<std::unique_ptr<Transport>> m_transport:
This extra verbosity is a bit of a turn-off. Can we add a forwarding constructor for class-type pointer wrappers (diff assumes the previous NotNullUniquePtr suggestion)?
diff --git a/src/net.cpp b/src/net.cpp
index fab392814e..aaf946f4ab 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -4007,9 +4007,9 @@ ServiceFlags CConnman::GetLocalServices() const
static util::NotNullUniquePtr<Transport> MakeTransport(NodeId id, bool use_v2transport, bool inbound) noexcept
{
if (use_v2transport) {
- return util::NotNullUniquePtr<Transport>{std::make_unique<V2Transport>(id, /*initiating=*/!inbound)};
+ return std::make_unique<V2Transport>(id, /*initiating=*/!inbound);
} else {
- return util::NotNullUniquePtr<Transport>{std::make_unique<V1Transport>(id)};
+ return std::make_unique<V1Transport>(id);
}
}
diff --git a/src/test/util_pointers_tests.cpp b/src/test/util_pointers_tests.cpp
index 38c49a5cd6..85807f8e73 100644
--- a/src/test/util_pointers_tests.cpp
+++ b/src/test/util_pointers_tests.cpp
@@ -63,6 +63,7 @@ BOOST_AUTO_TEST_CASE(check_swap)
BOOST_AUTO_TEST_CASE(check_deref)
{
int v{2};
+ static_assert(!std::is_convertible_v<int*, util::NotNull<int*>>); // Keep raw-pointer NotNull construction explicit.
util::NotNull p(&v);
*p = 3;
BOOST_CHECK_EQUAL(v, 3);
diff --git a/src/util/pointers.h b/src/util/pointers.h
index e757c6012b..73bb45e3e7 100644
--- a/src/util/pointers.h
+++ b/src/util/pointers.h
@@ -18,6 +18,7 @@
// are not needed.
// * Add NotNullUniquePtr and NotNullSharedPtr aliases to keep smart-pointer
// call sites readable.
+// * Add a forwarding constructor for concise non-null smart-pointer returns.
//
// All original code is covered by:
@@ -353,8 +354,13 @@ struct hash<gsl_detail::strict_not_null<T>> : gsl_detail::not_null_hash<gsl_deta
namespace util {
template <class T>
-struct NotNull : public gsl_detail::strict_not_null<T> {
- using gsl_detail::strict_not_null<T>::strict_not_null;
+struct NotNull : gsl_detail::strict_not_null<T> {
+ using Base = gsl_detail::strict_not_null<T>;
+ using Base::Base;
+
+ template <typename U>
+ requires (!std::is_pointer_v<T> && std::is_convertible_v<U, T>)
+ constexpr NotNull(U&& u) : Base{std::forward<U>(u)} {}
};
template <typename T>
NotNull(T) -> NotNull<T>;
Which obviously begs the question: do we ever want to convert back.
Given your hint for converting GetWalletForJSONRPCRequest it may be necessary (unless we propagate the type further), but I agree with you that this could also be done in a followup.
<details><summary>Migrate `GetWalletForJSONRPCRequest` to `util::NotNullSharedPtr<CWallet>`</summary>
diff --git a/src/util/pointers.h b/src/util/pointers.h
index 8f740472a3..5826e21cdc 100644
--- a/src/util/pointers.h
+++ b/src/util/pointers.h
@@ -21,6 +21,8 @@
// * Add a forwarding constructor for concise non-null smart-pointer returns.
// * Delete util::NotNull moves so the wrapper does not advertise misleading
// move operations.
+// * Add compatible shared_ptr conversions so NotNullSharedPtr<T> can initialize
+// std::shared_ptr<const T> callers without rebuilding the handle.
//
// All original code is covered by:
@@ -78,6 +80,12 @@ namespace details
const T,
const T&>;
+ template <typename T>
+ struct is_shared_ptr : std::false_type {};
+
+ template <typename T>
+ struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
+
} // namespace details
//
@@ -380,6 +388,10 @@ struct NotNull : gsl_detail::strict_not_null<T> {
// underlying smart pointer at transfer boundaries.
NotNull(NotNull&&) = delete;
NotNull& operator=(NotNull&&) = delete;
+
+ template <typename U>
+ requires (!std::is_same_v<U, T> && gsl_detail::details::is_shared_ptr<T>::value && gsl_detail::details::is_shared_ptr<U>::value && std::is_convertible_v<T, U>)
+ constexpr operator U() const { return this->get(); }
};
template <typename T>
NotNull(T) -> NotNull<T>;
diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp
index ed966d8944..9082407d6d 100644
--- a/src/wallet/rpc/addresses.cpp
+++ b/src/wallet/rpc/addresses.cpp
@@ -39,7 +39,6 @@ RPCMethod getnewaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -88,7 +87,6 @@ RPCMethod getrawchangeaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -132,7 +130,6 @@ RPCMethod setlabel()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -183,7 +180,6 @@ RPCMethod listaddressgroupings()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -232,7 +228,6 @@ RPCMethod keypoolrefill()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -423,7 +418,6 @@ RPCMethod getaddressinfo()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -536,7 +530,6 @@ RPCMethod getaddressesbylabel()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -600,7 +593,6 @@ RPCMethod listlabels()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -648,7 +640,6 @@ RPCMethod walletdisplayaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return UniValue::VNULL;
CWallet* const pwallet = wallet.get();
LOCK(pwallet->cs_wallet);
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 396be62825..a1cc43613c 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -50,7 +50,6 @@ RPCMethod importprunedfunds()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
CMutableTransaction tx;
if (!DecodeHexTx(tx, request.params[0].get_str())) {
@@ -108,7 +107,6 @@ RPCMethod removeprunedfunds()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -377,7 +375,6 @@ RPCMethod importdescriptors()
[](const RPCMethod& self, const JSONRPCRequest& main_request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(main_request);
- if (!pwallet) return UniValue::VNULL;
CWallet& wallet{*pwallet};
// Make sure the results are valid at least up to the most recent block
@@ -515,7 +512,6 @@ RPCMethod listdescriptors()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return UniValue::VNULL;
const bool priv = !request.params[0].isNull() && request.params[0].get_bool();
if (wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && priv) {
@@ -608,7 +604,6 @@ RPCMethod backupwallet()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
diff --git a/src/wallet/rpc/coins.cpp b/src/wallet/rpc/coins.cpp
index ab869b0d3f..8eadaf1ded 100644
--- a/src/wallet/rpc/coins.cpp
+++ b/src/wallet/rpc/coins.cpp
@@ -105,7 +105,6 @@ RPCMethod getreceivedbyaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -147,7 +146,6 @@ RPCMethod getreceivedbylabel()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -188,7 +186,6 @@ RPCMethod getbalance()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -258,7 +255,6 @@ RPCMethod lockunspent()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -376,7 +372,6 @@ RPCMethod listlockunspent()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
@@ -424,7 +419,6 @@ RPCMethod getbalances()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request);
- if (!rpc_wallet) return UniValue::VNULL;
const CWallet& wallet = *rpc_wallet;
// Make sure the results are valid at least up to the most recent block
@@ -520,7 +514,6 @@ RPCMethod listunspent()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
int nMinDepth = 1;
if (!request.params[0].isNull()) {
diff --git a/src/wallet/rpc/encrypt.cpp b/src/wallet/rpc/encrypt.cpp
index 68a80eb80e..ee2327ab98 100644
--- a/src/wallet/rpc/encrypt.cpp
+++ b/src/wallet/rpc/encrypt.cpp
@@ -35,7 +35,6 @@ RPCMethod walletpassphrase()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return UniValue::VNULL;
CWallet* const pwallet = wallet.get();
int64_t nSleepTime;
@@ -132,7 +131,6 @@ RPCMethod walletpassphrasechange()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
if (!pwallet->HasEncryptionKeys()) {
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
@@ -197,7 +195,6 @@ RPCMethod walletlock()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
if (!pwallet->HasEncryptionKeys()) {
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
@@ -250,7 +247,6 @@ RPCMethod encryptwallet()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: wallet does not contain private keys, nothing to encrypt.");
diff --git a/src/wallet/rpc/signmessage.cpp b/src/wallet/rpc/signmessage.cpp
index bd49f3e393..9073bf5762 100644
--- a/src/wallet/rpc/signmessage.cpp
+++ b/src/wallet/rpc/signmessage.cpp
@@ -37,7 +37,6 @@ RPCMethod signmessage()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
LOCK(pwallet->cs_wallet);
diff --git a/src/wallet/rpc/spend.cpp b/src/wallet/rpc/spend.cpp
index b6cdc8600f..e90e0772fa 100644
--- a/src/wallet/rpc/spend.cpp
+++ b/src/wallet/rpc/spend.cpp
@@ -288,7 +288,6 @@ RPCMethod sendtoaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -392,7 +391,6 @@ RPCMethod sendmany()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -799,7 +797,6 @@ RPCMethod fundrawtransaction()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// parse hex string from parameter
CMutableTransaction tx;
@@ -900,7 +897,6 @@ RPCMethod signrawtransactionwithwallet()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
CMutableTransaction mtx;
if (!DecodeHexTx(mtx, request.params[0].get_str())) {
@@ -1033,7 +1029,6 @@ static RPCMethod bumpfee_helper(std::string method_name)
[want_psbt](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER) && !want_psbt) {
throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
@@ -1263,7 +1258,6 @@ RPCMethod send()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options);
@@ -1377,7 +1371,6 @@ RPCMethod sendall()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)};
- if (!pwallet) return UniValue::VNULL;
// 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
pwallet->BlockUntilSyncedToCurrentChain();
@@ -1623,7 +1616,6 @@ RPCMethod walletprocesspsbt()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
const CWallet& wallet{*pwallet};
// Make sure the results are valid at least up to the most recent block
@@ -1755,7 +1747,6 @@ RPCMethod walletcreatefundedpsbt()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
CWallet& wallet{*pwallet};
// Make sure the results are valid at least up to the most recent block
diff --git a/src/wallet/rpc/transactions.cpp b/src/wallet/rpc/transactions.cpp
index 038e30fceb..784f8c2f92 100644
--- a/src/wallet/rpc/transactions.cpp
+++ b/src/wallet/rpc/transactions.cpp
@@ -225,7 +225,6 @@ RPCMethod listreceivedbyaddress()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -270,7 +269,6 @@ RPCMethod listreceivedbylabel()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -466,7 +464,6 @@ RPCMethod listtransactions()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -577,7 +574,6 @@ RPCMethod listsinceblock()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
const CWallet& wallet = *pwallet;
// Make sure the results are valid at least up to the most recent block
@@ -719,7 +715,6 @@ RPCMethod gettransaction()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -796,7 +791,6 @@ RPCMethod abandontransaction()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -844,7 +838,6 @@ RPCMethod rescanblockchain()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
CWallet& wallet{*pwallet};
// Make sure the results are valid at least up to the most recent block
@@ -932,7 +925,6 @@ RPCMethod abortrescan()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) return false;
pwallet->AbortRescan();
diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp
index 77a8745ced..80afdf7107 100644
--- a/src/wallet/rpc/util.cpp
+++ b/src/wallet/rpc/util.cpp
@@ -59,7 +59,7 @@ std::optional<std::string> GetWalletNameFromJSONRPCRequest(const JSONRPCRequest&
return std::nullopt;
}
-std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
+util::NotNullSharedPtr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
{
CHECK_NONFATAL(request.mode == JSONRPCRequest::EXECUTE);
WalletContext& context = EnsureWalletContext(request.context);
diff --git a/src/wallet/rpc/util.h b/src/wallet/rpc/util.h
index 88fdc6639f..0a77c0d906 100644
--- a/src/wallet/rpc/util.h
+++ b/src/wallet/rpc/util.h
@@ -7,6 +7,7 @@
#include <rpc/util.h>
#include <script/script.h>
+#include <util/pointers.h>
#include <wallet/wallet.h>
#include <any>
@@ -36,9 +37,9 @@ static const RPCResult RESULT_LAST_PROCESSED_BLOCK { RPCResult::Type::OBJ, "last
* Figures out what wallet, if any, to use for a JSONRPCRequest.
*
* [@param](/bitcoin-bitcoin/contributor/param/)[in] request JSONRPCRequest that wishes to access a wallet
- * [@return](/bitcoin-bitcoin/contributor/return/) nullptr if no wallet should be used, or a pointer to the CWallet
+ * [@return](/bitcoin-bitcoin/contributor/return/) a pointer to the selected CWallet, or throws if no wallet can be selected
*/
-std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
+util::NotNullSharedPtr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
std::optional<std::string> GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request);
/**
* Ensures that a wallet name is specified across the endpoint and wallet_name.
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index 8aa15c7ec5..72beaa6078 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -72,7 +72,6 @@ static RPCMethod getwalletinfo()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
// 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
@@ -304,7 +303,6 @@ static RPCMethod setwalletflag()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
std::string flag_str = request.params[0].get_str();
bool value = request.params[1].isNull() || request.params[1].get_bool();
@@ -516,7 +514,6 @@ RPCMethod simulaterawtransaction()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request);
- if (!rpc_wallet) return UniValue::VNULL;
const CWallet& wallet = *rpc_wallet;
LOCK(wallet.cs_wallet);
@@ -672,7 +669,6 @@ RPCMethod gethdkeys()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return UniValue::VNULL;
LOCK(wallet->cs_wallet);
@@ -770,7 +766,6 @@ static RPCMethod createwalletdescriptor()
[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
- if (!pwallet) return UniValue::VNULL;
std::optional<OutputType> output_type = ParseOutputType(request.params[0].get_str());
if (!output_type) {
@@ -860,7 +855,6 @@ RPCMethod addhdkey()
[&](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
- if (!wallet) return UniValue::VNULL;
if (wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "addhdkey is not available for wallets without private keys");
</details>