From 09eacee6b2844edf4f804e77180489cf31383143 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 15 Jun 2017 13:49:38 -0400 Subject: [PATCH 1/4] [wallet] fix comment for CWallet::Verify() --- src/wallet/wallet.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index bcd7e4b4e..7ef2e6f1d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1066,7 +1066,9 @@ public: //! 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(); /** From 4a057152d2635e5a4cff8fd654087fee044efef6 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 15 Jun 2017 11:45:08 -0400 Subject: [PATCH 2/4] [wallet] [rpc] print wallet name in getwalletinfo --- src/wallet/rpcwallet.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4275a9181..030f203d2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2447,6 +2447,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request) "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 confirmed balance of the wallet in " + CURRENCY_UNIT + "\n" " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" @@ -2469,6 +2470,7 @@ UniValue getwalletinfo(const JSONRPCRequest& request) 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", ValueFromAmount(pwallet->GetUnconfirmedBalance()))); From 9508761ed69a30f4af24fbc9274176056431abfb Mon Sep 17 00:00:00 2001 From: John Newbery Date: Tue, 27 Jun 2017 09:46:55 -0400 Subject: [PATCH 3/4] [wallet] [rpc] Add listwallets RPC This commit adds a listwallets RPC, which lists the names of the currently loaded wallets. This command intentionally shows no information about the wallet other then the name. Information on individual wallets can be obtained using the getwalletinfo RPC. --- src/wallet/rpcwallet.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 030f203d2..2b7b4085e 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2491,6 +2491,39 @@ UniValue getwalletinfo(const JSONRPCRequest& request) return obj; } +UniValue listwallets(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; +} + UniValue resendwallettransactions(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); @@ -3087,6 +3120,7 @@ static const CRPCCommand commands[] = { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} }, { "wallet", "listtransactions", &listtransactions, false, {"account","count","skip","include_watchonly"} }, { "wallet", "listunspent", &listunspent, false, {"minconf","maxconf","addresses","include_unsafe","query_options"} }, + { "wallet", "listwallets", &listwallets, true, {} }, { "wallet", "lockunspent", &lockunspent, true, {"unlock","transactions"} }, { "wallet", "move", &movecmd, false, {"fromaccount","toaccount","amount","minconf","comment"} }, { "wallet", "sendfrom", &sendfrom, false, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} }, From 3707fcd94e6251384235d16faafc975853d49e3d Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 15 Jun 2017 09:05:32 -0400 Subject: [PATCH 4/4] [wallet] [tests] Add listwallets to multiwallet test --- test/functional/multiwallet.py | 31 +++++++++++++++++++++---------- test/functional/test_runner.py | 1 + 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py index 2b4dd2d3e..f0929a8e2 100755 --- a/test/functional/multiwallet.py +++ b/test/functional/multiwallet.py @@ -2,9 +2,12 @@ # Copyright (c) 2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -"""Test multiwallet.""" +"""Test multiwallet. + +Verify that a bitcoind node can load multiple wallet files +""" 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): @@ -18,20 +21,28 @@ class MultiWalletTest(BitcoinTestFramework): w1 = self.nodes[0] / "wallet/w1" w1.generate(1) - #accessing wallet RPC without using wallet endpoint fails + # accessing wallet RPC without using wallet endpoint fails assert_raises_jsonrpc(-32601, "Method not found", self.nodes[0].getwalletinfo) - #check w1 wallet balance - walletinfo = w1.getwalletinfo() - assert_equal(walletinfo['immature_balance'], 50) + # check w1 wallet balance + 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 + # 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) assert_equal(w2.getbalance(), 0) diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 51577589f..c158eaa34 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -89,6 +89,7 @@ BASE_SCRIPTS= [ 'mempool_spendcoinbase.py', 'mempool_reorg.py', 'mempool_persist.py', + 'multiwallet.py', 'httpbasics.py', 'multi_rpc.py', 'proxy_test.py',