diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2921,6 +2921,7 @@ "Returns an object containing various wallet state info.\n" "\nResult:\n" "{\n" + " \"walletname\": xxxxx, (string) the wallet name\n" " \"walletversion\": xxxxx, (numeric) the wallet " "version\n" " \"balance\": xxxxxxx, (numeric) the total " @@ -2957,12 +2958,12 @@ HelpExampleCli("getwalletinfo", "") + HelpExampleRpc("getwalletinfo", "")); } - LOCK2(cs_main, pwallet->cs_wallet); UniValue obj(UniValue::VOBJ); size_t kpExternalSize = pwallet->KeypoolCountExternalKeys(); + obj.push_back(Pair("walletname", pwallet->GetName())); obj.push_back(Pair("walletversion", pwallet->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance()))); obj.push_back(Pair("unconfirmed_balance", @@ -2988,6 +2989,38 @@ return obj; } +static UniValue listwallets(const Config &config, + const JSONRPCRequest &request) { + if (request.fHelp || request.params.size() != 0) + throw std::runtime_error( + "listwallets\n" + "Returns a list of currently loaded wallets.\n" + "For full information on the wallet, use \"getwalletinfo\"\n" + "\nResult:\n" + "[ (json array of strings)\n" + " \"walletname\" (string) the wallet name\n" + " ...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("listwallets", "") + + HelpExampleRpc("listwallets", "")); + + UniValue obj(UniValue::VARR); + + for (CWalletRef pwallet : vpwallets) { + + if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { + return NullUniValue; + } + + LOCK(pwallet->cs_wallet); + + obj.push_back(pwallet->GetName()); + } + + return obj; +} + static UniValue resendwallettransactions(const Config &config, const JSONRPCRequest &request) { CWallet *const pwallet = GetWalletForJSONRPCRequest(request); @@ -3484,6 +3517,7 @@ { "wallet", "listreceivedbyaddress", listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} }, { "wallet", "listsinceblock", listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} }, { "wallet", "listtransactions", listtransactions, false, {"account","count","skip","include_watchonly"} }, + { "wallet", "listwallets", listwallets, true, {} }, { "wallet", "listunspent", listunspent, false, {"minconf","maxconf","addresses","include_unsafe"} }, { "wallet", "lockunspent", lockunspent, true, {"unlock","transactions"} }, { "wallet", "move", movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} }, @@ -3497,7 +3531,7 @@ { "wallet", "walletpassphrasechange", walletpassphrasechange, true, {"oldpassphrase","newpassphrase"} }, { "wallet", "walletpassphrase", walletpassphrase, true, {"passphrase","timeout"} }, - { "generating", "generate", &generate, true, {"nblocks","maxtries"} }, + { "generating", "generate", generate, true, {"nblocks","maxtries"} }, }; // clang-format on diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1040,7 +1040,12 @@ //! Flush wallet (bitdb flush) void Flush(bool shutdown = false); - //! Verify the wallet database and perform salvage if required + //! Responsible for reading and validating the -wallet arguments and + //! verifying the wallet database. + // This function will perform salvage on the wallet if requested, as long + // as only one wallet is + // being loaded (CWallet::ParameterInteraction forbids -salvagewallet, + // -zapwallettxes or -upgradewallet with multiwallet). static bool Verify(); /** diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py --- a/test/functional/multiwallet.py +++ b/test/functional/multiwallet.py @@ -9,7 +9,7 @@ import os from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import * +from test_framework.util import assert_equal, assert_raises_jsonrpc class MultiWalletTest(BitcoinTestFramework): @@ -51,17 +51,24 @@ # accessing wallet RPC without using wallet endpoint fails assert_raises_jsonrpc(-19, "Wallet file not specified (must request wallet RPC through /wallet/ uri-path).", self.nodes[0].getwalletinfo) - # check w1 wallet balance - walletinfo = w1.getwalletinfo() - assert_equal(walletinfo['immature_balance'], 50) + w1_info = w1.getwalletinfo() + assert_equal(w1_info['immature_balance'], 50) + w1_name = w1_info['walletname'] + assert_equal(w1_name, "w1") # check w1 wallet balance w2 = self.nodes[0] / "wallet/w2" - walletinfo = w2.getwalletinfo() - assert_equal(walletinfo['immature_balance'], 0) + w2_info = w2.getwalletinfo() + assert_equal(w2_info['immature_balance'], 0) + w2_name = w2_info['walletname'] + assert_equal(w2_name, "w2") w3 = self.nodes[0] / "wallet/w3" + w3_name = w3.getwalletinfo()['walletname'] + assert_equal(w3_name, "w3") + + assert_equal({"w1", "w2", "w3"}, {w1_name, w2_name, w3_name}) w1.generate(101) assert_equal(w1.getbalance(), 100)