Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically Loadable Multiple Wallet Support Complete!!! #2124

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
71c63e3
Added multiple wallet support
CodeShark Dec 21, 2012
4a6b0e2
Added CWallet* parameter to RPC test suite and a CWalletMap instance …
CodeShark Dec 24, 2012
158ce39
Fixed RPC issues detected by test suite.
CodeShark Dec 24, 2012
1b640c1
Added loading of wallet names and files from -usewallet arguments
CodeShark Dec 24, 2012
1cdf18b
TxMemPool::accept() calls SyncWithWallets(), so all mempool transacti…
CodeShark Dec 24, 2012
27fa196
Modified getinfo RPC call to return an array of wallets
CodeShark Dec 24, 2012
93e6b80
Removed dependency on wallet encryption state for getting help on RPC…
CodeShark Dec 24, 2012
0f815bf
usewallet now checks whether method is valid.
CodeShark Dec 24, 2012
924f088
Fixed LOCK to lock appropriate wallet.
CodeShark Dec 25, 2012
fa1c808
Fixed wallet load time indicator.
CodeShark Dec 25, 2012
b0cae87
Moved wallet detail information out of getinfo and put it in listwall…
CodeShark Dec 26, 2012
2b31fdf
Moved code for locking a wallet automatically at a certain time from …
CodeShark Dec 26, 2012
1b51a7f
Dynamic loading and unloading of wallets.
CodeShark Dec 27, 2012
3fd110a
New naming scheme for wallets. Checks for valid character set. CWalle…
CodeShark Dec 27, 2012
9d201cf
More load options at startup.
CodeShark Dec 27, 2012
2256d1d
Thread-safe CWalletMap.
CodeShark Dec 27, 2012
3f5d692
Using GetWallet instead of pWalletMap->wallets.find
CodeShark Dec 29, 2012
629ca2f
Using GetWallet instead of pWalletMap->wallets.find
CodeShark Dec 29, 2012
55d301c
Merge branch 'multiwallet' of 108.60.150.142:../gitrepos/bitcoin into…
CodeShark Dec 29, 2012
ebf85b1
Moved RPC type conversion for usewallet to RPCConvertValues function.
CodeShark Jan 7, 2013
74228a2
Fixed usewallet params.
CodeShark Jan 7, 2013
ec0cc4b
Added preprocessor directive for boost filesystem v2 vs v3.
CodeShark Jan 10, 2013
7348f78
Better encapsulation on WalletMap class, moved critical section locks…
CodeShark Jan 10, 2013
d21a960
Checking for CDB exceptions upon loading wallet.
CodeShark Jan 10, 2013
f409a6d
Added unload methods for wallet db and call to unload in ~CWallet().
CodeShark Jan 10, 2013
6215e53
Fixed test_bitcoin issue.
CodeShark Jan 10, 2013
d8b0cf1
Added locks on setpwalletRegistered functions.
CodeShark Jan 10, 2013
3d15116
Added ReacceptWalletTransactions() registered wallet function in main…
CodeShark Jan 10, 2013
aa93b31
Added -lboost_regex to bitcoin-qt.pro.
CodeShark Jan 10, 2013
e0f3cbe
Made wallet pointers in CWalletMap boost::shared_ptr<CWallet>.
CodeShark Jan 11, 2013
eba5579
Removed pwalletMain. Using pWalletMap->GetDefaultWallet() instead.
CodeShark Jan 11, 2013
6f3e40b
Renamed CWalletMap CWalletManager and pWalletMap pWalletManager.
CodeShark Jan 11, 2013
3944f1d
Added Timer
CodeShark Jan 12, 2013
64a9b45
Integrated timer with wallet.
CodeShark Jan 13, 2013
a240960
Added wallet unloading tracers. Let rpcmining methods use nondefault …
CodeShark Jan 14, 2013
41f561c
Changed the way unlock time displays in listwallets.
CodeShark Jan 14, 2013
5bb560f
Made wallet unlock timestamp UTC.
CodeShark Jan 14, 2013
6c7f86a
Merged multiwallet(5bb560f) with master.
CodeShark Jan 19, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
151 changes: 81 additions & 70 deletions src/bitcoinrpc.cpp
Expand Up @@ -141,7 +141,7 @@ string CRPCTable::help(string strCommand) const
Array params;
rpcfn_type pfn = pcmd->actor;
if (setDone.insert(pfn).second)
(*pfn)(params, true);
(*pfn)(NULL, params, true);
}
catch (std::exception& e)
{
Expand All @@ -159,7 +159,7 @@ string CRPCTable::help(string strCommand) const
return strRet;
}

Value help(const Array& params, bool fHelp)
Value help(CWallet* pWallet, const Array& params, bool fHelp)
{
if (fHelp || params.size() > 1)
throw runtime_error(
Expand All @@ -174,7 +174,7 @@ Value help(const Array& params, bool fHelp)
}


Value stop(const Array& params, bool fHelp)
Value stop(CWallet* pWallet, const Array& params, bool fHelp)
{
// Accept the deprecated and ignored 'detach´ boolean argument
if (fHelp || params.size() > 1)
Expand All @@ -194,68 +194,72 @@ Value stop(const Array& params, bool fHelp)


static const CRPCCommand vRPCCommands[] =
{ // name function safemd unlocked
// ------------------------ ----------------------- ------ --------
{ "help", &help, true, true },
{ "stop", &stop, true, true },
{ "getblockcount", &getblockcount, true, false },
{ "getconnectioncount", &getconnectioncount, true, false },
{ "getpeerinfo", &getpeerinfo, true, false },
{ "getdifficulty", &getdifficulty, true, false },
{ "getgenerate", &getgenerate, true, false },
{ "setgenerate", &setgenerate, true, false },
{ "gethashespersec", &gethashespersec, true, false },
{ "getinfo", &getinfo, true, false },
{ "getmininginfo", &getmininginfo, true, false },
{ "getnewaddress", &getnewaddress, true, false },
{ "getaccountaddress", &getaccountaddress, true, false },
{ "setaccount", &setaccount, true, false },
{ "getaccount", &getaccount, false, false },
{ "getaddressesbyaccount", &getaddressesbyaccount, true, false },
{ "sendtoaddress", &sendtoaddress, false, false },
{ "getreceivedbyaddress", &getreceivedbyaddress, false, false },
{ "getreceivedbyaccount", &getreceivedbyaccount, false, false },
{ "listreceivedbyaddress", &listreceivedbyaddress, false, false },
{ "listreceivedbyaccount", &listreceivedbyaccount, false, false },
{ "backupwallet", &backupwallet, true, false },
{ "keypoolrefill", &keypoolrefill, true, false },
{ "walletpassphrase", &walletpassphrase, true, false },
{ "walletpassphrasechange", &walletpassphrasechange, false, false },
{ "walletlock", &walletlock, true, false },
{ "encryptwallet", &encryptwallet, false, false },
{ "validateaddress", &validateaddress, true, false },
{ "getbalance", &getbalance, false, false },
{ "move", &movecmd, false, false },
{ "sendfrom", &sendfrom, false, false },
{ "sendmany", &sendmany, false, false },
{ "addmultisigaddress", &addmultisigaddress, false, false },
{ "createmultisig", &createmultisig, true, true },
{ "getrawmempool", &getrawmempool, true, false },
{ "getblock", &getblock, false, false },
{ "getblockhash", &getblockhash, false, false },
{ "gettransaction", &gettransaction, false, false },
{ "listtransactions", &listtransactions, false, false },
{ "listaddressgroupings", &listaddressgroupings, false, false },
{ "signmessage", &signmessage, false, false },
{ "verifymessage", &verifymessage, false, false },
{ "getwork", &getwork, true, false },
{ "listaccounts", &listaccounts, false, false },
{ "settxfee", &settxfee, false, false },
{ "getblocktemplate", &getblocktemplate, true, false },
{ "submitblock", &submitblock, false, false },
{ "listsinceblock", &listsinceblock, false, false },
{ "dumpprivkey", &dumpprivkey, false, false },
{ "importprivkey", &importprivkey, false, false },
{ "listunspent", &listunspent, false, false },
{ "getrawtransaction", &getrawtransaction, false, false },
{ "createrawtransaction", &createrawtransaction, false, false },
{ "decoderawtransaction", &decoderawtransaction, false, false },
{ "signrawtransaction", &signrawtransaction, false, false },
{ "sendrawtransaction", &sendrawtransaction, false, false },
{ "gettxoutsetinfo", &gettxoutsetinfo, true, false },
{ "gettxout", &gettxout, true, false },
{ "lockunspent", &lockunspent, false, false },
{ "listlockunspent", &listlockunspent, false, false },
{ // name function safemd unlocked isWalletFn
// ------------------------ ----------------------- ------ -------- ----------
{ "help", &help, true, true, false },
{ "stop", &stop, true, true, false },
{ "getblockcount", &getblockcount, true, false, false },
{ "getconnectioncount", &getconnectioncount, true, false, false },
{ "getpeerinfo", &getpeerinfo, true, false, false },
{ "getdifficulty", &getdifficulty, true, false, false },
{ "getgenerate", &getgenerate, true, false, false },
{ "setgenerate", &setgenerate, true, false, false },
{ "gethashespersec", &gethashespersec, true, false, false },
{ "getinfo", &getinfo, true, false, false },
{ "getmininginfo", &getmininginfo, true, false, false },
{ "getnewaddress", &getnewaddress, true, false, true },
{ "getaccountaddress", &getaccountaddress, true, false, true },
{ "setaccount", &setaccount, true, false, true },
{ "getaccount", &getaccount, false, false, true },
{ "getaddressesbyaccount", &getaddressesbyaccount, true, false, true },
{ "sendtoaddress", &sendtoaddress, false, false, true },
{ "getreceivedbyaddress", &getreceivedbyaddress, false, false, true },
{ "getreceivedbyaccount", &getreceivedbyaccount, false, false, true },
{ "listreceivedbyaddress", &listreceivedbyaddress, false, false, true },
{ "listreceivedbyaccount", &listreceivedbyaccount, false, false, true },
{ "backupwallet", &backupwallet, true, false, true },
{ "keypoolrefill", &keypoolrefill, true, false, true },
{ "walletpassphrase", &walletpassphrase, true, false, true },
{ "walletpassphrasechange", &walletpassphrasechange, false, false, true },
{ "walletlock", &walletlock, true, false, true },
{ "encryptwallet", &encryptwallet, false, false, true },
{ "validateaddress", &validateaddress, true, false, true },
{ "getbalance", &getbalance, false, false, true },
{ "move", &movecmd, false, false, true },
{ "sendfrom", &sendfrom, false, false, true },
{ "sendmany", &sendmany, false, false, true },
{ "addmultisigaddress", &addmultisigaddress, false, false, true },
{ "createmultisig", &createmultisig, true, true, true },
{ "getrawmempool", &getrawmempool, true, false, false },
{ "getblock", &getblock, false, false, false },
{ "getblockhash", &getblockhash, false, false, false },
{ "gettransaction", &gettransaction, false, false, true },
{ "listtransactions", &listtransactions, false, false, true },
{ "listaddressgroupings", &listaddressgroupings, false, false, true },
{ "signmessage", &signmessage, false, false, true },
{ "verifymessage", &verifymessage, false, false, false },
{ "getwork", &getwork, true, false, false },
{ "listaccounts", &listaccounts, false, false, true },
{ "settxfee", &settxfee, false, false, false },
{ "getblocktemplate", &getblocktemplate, true, false, false },
{ "submitblock", &submitblock, false, false, false },
{ "listsinceblock", &listsinceblock, false, false, true },
{ "dumpprivkey", &dumpprivkey, false, false, true },
{ "importprivkey", &importprivkey, false, false, true },
{ "listunspent", &listunspent, false, false, true },
{ "getrawtransaction", &getrawtransaction, false, false, false },
{ "createrawtransaction", &createrawtransaction, false, false, false },
{ "decoderawtransaction", &decoderawtransaction, false, false, false },
{ "signrawtransaction", &signrawtransaction, false, false, true },
{ "sendrawtransaction", &sendrawtransaction, false, false, false },
{ "gettxoutsetinfo", &gettxoutsetinfo, true, false, false },
{ "gettxout", &gettxout, true, false, true },
{ "lockunspent", &lockunspent, false, false, true },
{ "listlockunspent", &listlockunspent, false, false, true },
{ "listwallets", &listwallets, true, true, false },
{ "usewallet", &usewallet, false, true, false },
{ "loadwallet", &loadwallet, false, true, false },
{ "unloadwallet", &unloadwallet, false, true, false }
};

CRPCTable::CRPCTable()
Expand Down Expand Up @@ -1052,7 +1056,7 @@ void ThreadRPCServer3(void* parg)
}
}

json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params) const
json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array &params, CWallet* pWallet) const
{
// Find method
const CRPCCommand *pcmd = tableRPC[strMethod];
Expand All @@ -1065,16 +1069,20 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
!pcmd->okSafeMode)
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);

if (!pWallet) pWallet = pwalletMain;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should use pWalletMap->GetDefaultWallet() wherever pwalletMain appears anywhere in the application.


try
{
// Execute
Value result;
{
if (pcmd->unlocked)
result = pcmd->actor(params, false);
LOCK(pWalletMap->cs_WalletMap);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you want to keep the walletmap locked during the actual RPC execution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agreed - this was just me being extra cautious until the locking issues can be further looked into.

if (pcmd->unlocked) {
result = pcmd->actor(pWallet, params, false);
}
else {
LOCK2(cs_main, pwalletMain->cs_wallet);
result = pcmd->actor(params, false);
LOCK2(cs_main, pWallet->cs_wallet);
result = pcmd->actor(pWallet, params, false);
}
}
return result;
Expand Down Expand Up @@ -1220,6 +1228,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
if (strMethod == "lockunspent" && n > 1) ConvertTo<Array>(params[1]);
if (strMethod == "importprivkey" && n > 2) ConvertTo<bool>(params[2]);
if (strMethod == "loadwallet" && n > 1) ConvertTo<bool>(params[1]);
if (strMethod == "loadwallet" && n > 2) ConvertTo<bool>(params[2]);
if (strMethod == "loadwallet" && n > 3) ConvertTo<boost::int64_t>(params[3]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't RPCConvertValues need some magic to deal with usewallet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usewallet used to call RPCConvertValues on the parameters and pass it to CRPCTable::execute.

Now RPCConvertValues does the magic.


return params;
}
Expand Down