Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
RPC refactoring: Access wallet using new GetWalletForJSONRPCRequest #8775
Conversation
MarcoFalke
added
RPC/REST/ZMQ
Wallet
labels
Sep 21, 2016
|
I don't like the coupling and the I think we should pack the request path (URI) into the Instead of the |
|
General ConceptACK on a |
| @@ -70,7 +70,8 @@ UniValue getinfo(const UniValue& params, bool fHelp) | ||
| ); | ||
| #ifdef ENABLE_WALLET | ||
| - LOCK2(cs_main, pwalletMain ? &pwalletMain->cs_wallet : NULL); | ||
| + CWallet *& pwallet = reqinfo.wallet; |
That sounds nice, but greatly complicates the implementation. :( |
jonasschnelli
referenced this pull request
Sep 22, 2016
Merged
[RPC] Give RPC commands more information about the RPC request #8788
|
I think this can be closed after #8788? |
|
Closing in favor of merged #8788 |
jonasschnelli
closed this
Oct 19, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Oct 20, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Oct 20, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Oct 20, 2016
laanwj
reopened this
Oct 25, 2016
|
Rebased and refactored based on @jonasschnelli 's idea. |
|
Makes sense, utACK ab5ce98 |
| @@ -26,6 +26,8 @@ | ||
| using namespace std; | ||
| +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); |
laanwj
Oct 25, 2016
Owner
Not sure how this can pass the build w/ --disable-wallet, but this should be bracketed with #ifdef ENABLE_WALLET
|
Rebased and addressed nit |
luke-jr
changed the title from
RPC refactoring: Never access wallet directly, only via new CRPCRequestInfo
to
RPC refactoring: Access wallet using new GetWalletForJSONRPCRequest
Nov 12, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Dec 31, 2016
|
utACK 7de5573 |
|
Minor change: Forward-declared CWallet even for non-wallet builds so it can be used in a pointer type, avoiding unnecessary casting. |
| @@ -35,6 +35,11 @@ | ||
| using namespace std; | ||
| +#ifdef ENABLE_WALLET | ||
| +std::string HelpRequiringPassphrase(CWallet *); |
TheBlueMatt
Jan 6, 2017
Contributor
I'd kinda prefer we add another declaration outside of a header in an unrelated file...can we keep it in server.h and ifdef ENABLE_WALLET it?
luke-jr
Jan 6, 2017
Member
I suppose we could. But then it's more likely to get used in new code (which I think we want to discourage?)
TheBlueMatt
Jan 6, 2017
Contributor
I'd think we can (and, more importantly, would) still nag people submitting PRs which add more uses of it outside of src/wallet/rpc*.
| @@ -26,6 +26,10 @@ | ||
| using namespace std; | ||
| +#ifdef ENABLE_WALLET | ||
| +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); |
| @@ -35,6 +35,11 @@ | ||
| using namespace std; | ||
| +#ifdef ENABLE_WALLET | ||
| +std::string HelpRequiringPassphrase(CWallet *); |
TheBlueMatt
Jan 6, 2017
Contributor
I'd think we can (and, more importantly, would) still nag people submitting PRs which add more uses of it outside of src/wallet/rpc*.
| @@ -29,6 +29,7 @@ | ||
| using namespace std; | ||
| +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest&); | ||
| void EnsureWalletIsUnlocked(CWallet *); | ||
| bool EnsureWalletIsAvailable(CWallet *, bool avoidException); |
TheBlueMatt
Jan 6, 2017
Contributor
Can we move these to some rpc.h in src/wallet? Why are we declaring functions in another file from the definition if they're both in src/wallet???
| @@ -30,6 +30,11 @@ using namespace std; | ||
| int64_t nWalletUnlockTime; | ||
| static CCriticalSection cs_nWalletUnlockTime; | ||
| +CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) |
TheBlueMatt
Jan 6, 2017
Contributor
Can you document this function somewhere (also probably move its definition to src/wallet/rpcwallet.h) - a few places in src/wallet assume it always returns non-NULL but this is not documented (I havent looked at the actual multi-wallet PR, but does this function then throw an RPC exception if you ask for a wallet that isnt loaded, or does it return NULL then)?
|
So in some cases in the RPC you get the wallet pointer from json but then the check if it's available is far below. This is begging for someone to insert code that uses a potentially null pointer between to two and doesn't notice because their function doesn't get tested with a missing wallet. I would recommend moving the creation of that local pointer down to the point where you're going to test it. Alternatively or in addition, rename GetWalletForJSONRPCRequest to TryGetWalletForJSONRPCRequest and make GetWalletForJSONRPCRequest a wrapper for it that throws when it fails? Other than this nit that perhaps getting the pointer and testing it are too separated in some cases, utACK. |
|
I liked the TryGetWalletForJSONRPCRequest/GetWalletForJSONRPCRequest refactor idea, but I don't see any clean way to do it without changing the So I moved the one case EnsureWalletIsAvailable was delayed up, and removed the blank line between them and GetWalletForJSONRPCRequest. |
TheBlueMatt
reviewed
Jan 7, 2017
Please do not tag the 4th commit "Trivial". We usually define trivial as doesnt touch any code.
As for the 6th commit: please do not do this. nothing in src/wallet is built when ENABLE_WALLET is off, so generally src/wallet/* should never be included outside of src/wallet/*
Aside from the (partial-revert) of "Move wallet RPC declarations to rpcwallet.h" and the printing of the raw pointers to debug log, this looks good to me at d9aff6e.
| -void ImportAddress(const CBitcoinAddress& address, const string& strLabel); | ||
| -void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) | ||
| +void ImportAddress(CWallet*, const CBitcoinAddress& address, const string& strLabel); | ||
| +void ImportScript(CWallet * const pwallet, const CScript& script, const string& strLabel, bool isRedeemScript) |
TheBlueMatt
Jan 7, 2017
Contributor
Note that there are a ton of uses of pwalletMain in ImportScript after the first commit ("RPC/Wallet: Pass CWallet as pointer to helper functions") which are fixed in the next ("RPC: Do all wallet access through new GetWalletForJSONRPCRequest") when they belong in the first.
ryanofsky
Feb 27, 2017
Contributor
Note that there are a ton of uses of pwalletMain in ImportScript after the first commit ("RPC/Wallet: Pass CWallet as pointer to helper functions") which are fixed in the next ("RPC: Do all wallet access through new GetWalletForJSONRPCRequest") when they belong in the first.
I'm not seeing function signatures changes in c68b5a8 RPC: Do all wallet access through new GetWalletForJSONRPCRequest so the two commits do seem distinct currently.
| - nWalletUnlockTime = GetTime() + nSleepTime; | ||
| - RPCRunLater("lockwallet", boost::bind(LockWallet, pwallet), nSleepTime); | ||
| + pwallet->nRelockTime = GetTime() + nSleepTime; | ||
| + RPCRunLater(strprintf("lockwallet_%u", uintptr_t(pwallet)), boost::bind(LockWallet, pwallet), nSleepTime); |
TheBlueMatt
Jan 7, 2017
Contributor
I super dont like the fact that the pointer to the wallet will end up in debug.log if you have debug=rpc enabled.
ryanofsky
Feb 27, 2017
Contributor
I super dont like the fact that the pointer to the wallet will end up in debug.log if you have debug=rpc enabled.
Is fixed in later commit c42f3a5 Wallet/RPC: Use filename rather than CWallet pointer, for lockwallet RPCRunLater job name
| @@ -340,8 +349,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) | ||
| // Find all addresses that have the given account | ||
| UniValue ret(UniValue::VARR); | ||
| - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) | ||
| - { | ||
| + for (const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item : pwallet->mapAddressBook) { |
TheBlueMatt
Jan 7, 2017
Contributor
nit: I believe you can remove the PAIRTYPE and replace with std::pair since we're not using BOOST_FOREACH now.
| @@ -1126,7 +1129,7 @@ struct tallyitem | ||
| } | ||
| }; | ||
| -UniValue ListReceived(const UniValue& params, bool fByAccounts) | ||
| +UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts) |
TheBlueMatt
Jan 7, 2017
Contributor
Note that there are a ton of uses of pwalletMain in ListReceived after the first commit ("RPC/Wallet: Pass CWallet as pointer to helper functions") which are fixed in the next ("RPC: Do all wallet access through new GetWalletForJSONRPCRequest") when they belong in the first.
| @@ -1219,8 +1241,7 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA | ||
| // Reply | ||
| UniValue ret(UniValue::VARR); | ||
| map<string, tallyitem> mapAccountTally; | ||
| - BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwallet->mapAddressBook) | ||
| - { | ||
| + for (const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item : pwallet->mapAddressBook) { |
| @@ -1635,14 +1665,14 @@ UniValue listaccounts(const JSONRPCRequest& request) | ||
| includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY; | ||
| map<string, CAmount> mapAccountBalances; | ||
| - BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& entry, pwallet->mapAddressBook) { | ||
| - if (IsMine(*pwallet, entry.first) & includeWatchonly) // This address belongs to me | ||
| + for (const PAIRTYPE(CTxDestination, CAddressBookData)& entry : pwallet->mapAddressBook) { |
|
@luke-jr Looks good to me, will test as soon as you update for matt's latest comments. |
|
Made changes requested by @TheBlueMatt, and rebased to resolve conflict. Also includes a quick sanity check that -wallet doesn't include path separators. |
|
While you're at it, can you call SanitizeString (in addition to the "/\" check) on the wallet param? |
|
utACK 7d1228b |
|
Needs rebase. |
|
ACK. |
|
Needs rebasing again. |
|
Rebased yet again. |
|
still ACK |
| @@ -3740,6 +3740,12 @@ bool CWallet::InitLoadWallet() | ||
| std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); |
BlockMechanic
Feb 16, 2017
Should this not be "count" i.e for multiple wallet files to be created ? Adding perhaps a for loop to iterate over required num of wallets?
ryanofsky
referenced this pull request
Feb 27, 2017
Closed
[Wallet] get rid of pwalletMain, add simple CWallets infrastructure #8764
luke-jr
added some commits
Sep 9, 2016
| @@ -112,13 +112,17 @@ UniValue getinfo(const JSONRPCRequest& request) | ||
| class DescribeAddressVisitor : public boost::static_visitor<UniValue> | ||
| { | ||
| public: | ||
| + CWallet * const pwallet; |
ryanofsky
Feb 27, 2017
Contributor
Seems like this could be a pointer to a const CWallet. Same for some other cases. Would suggest using const CWallet* instead of CWallet* where possible for more safety and clarity.
| @@ -101,8 +101,9 @@ UniValue getinfo(const JSONRPCRequest& request) | ||
| obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime())); | ||
| obj.push_back(Pair("keypoolsize", (int)pwallet->GetKeyPoolSize())); | ||
| } | ||
| - if (pwallet && pwallet->IsCrypted()) | ||
| + if (pwallet && pwallet->IsCrypted()) { |
ryanofsky
Feb 27, 2017
Contributor
Commit 09f3076 Reformat touched lines with C++11 looks fine, but it doesn't appear that these changes have anything to do with C++11. Maybe clarify commit message.
| @@ -234,6 +235,9 @@ UniValue validateaddress(const JSONRPCRequest& request) | ||
| return ret; | ||
| } | ||
| +// Needed even with !ENABLE_WALLET, to pass (ignored) pointers around | ||
| +class CWallet; |
ryanofsky
Feb 27, 2017
Contributor
This doesn't actually seem to be needed since CWallet is also forward declared in init.h, but maybe it is better to keep it.
| - if (pwalletMain) { | ||
| - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); | ||
| - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); | ||
| + if (pwallet) { |
ryanofsky
Feb 27, 2017
Contributor
Note to reviewers: This commit (d77ad6d RPC: Do all wallet access through new GetWalletForJSONRPCRequest) is trivial to review if you configure your diff tool to ignore the pwallet->pwalletmain renames (much shorter and no changed lines, only inserted).
| + | ||
| +#ifdef ENABLE_WALLET | ||
| +// New code should accessing the wallet should be under the ../wallet/ directory | ||
| +std::string HelpRequiringPassphrase(CWallet *); |
ryanofsky
Feb 27, 2017
Contributor
Maybe squash commit 6033b43 Move wallet RPC declarations to rpcwallet.h into commit f757a41 RPC/Wallet: Pass CWallet as pointer to helper functions, to just add to right place instead of adding and moving.
| -void ImportAddress(const CBitcoinAddress& address, const string& strLabel); | ||
| -void ImportScript(const CScript& script, const string& strLabel, bool isRedeemScript) | ||
| +void ImportAddress(CWallet*, const CBitcoinAddress& address, const string& strLabel); | ||
| +void ImportScript(CWallet * const pwallet, const CScript& script, const string& strLabel, bool isRedeemScript) |
ryanofsky
Feb 27, 2017
Contributor
Note that there are a ton of uses of pwalletMain in ImportScript after the first commit ("RPC/Wallet: Pass CWallet as pointer to helper functions") which are fixed in the next ("RPC: Do all wallet access through new GetWalletForJSONRPCRequest") when they belong in the first.
I'm not seeing function signatures changes in c68b5a8 RPC: Do all wallet access through new GetWalletForJSONRPCRequest so the two commits do seem distinct currently.
| @@ -2063,9 +2060,8 @@ UniValue walletpassphrase(const JSONRPCRequest& request) | ||
| pwallet->TopUpKeyPool(); | ||
| int64_t nSleepTime = request.params[1].get_int64(); | ||
| - LOCK(cs_nWalletUnlockTime); |
| - nWalletUnlockTime = GetTime() + nSleepTime; | ||
| - RPCRunLater("lockwallet", boost::bind(LockWallet, pwallet), nSleepTime); | ||
| + pwallet->nRelockTime = GetTime() + nSleepTime; | ||
| + RPCRunLater(strprintf("lockwallet_%u", uintptr_t(pwallet)), boost::bind(LockWallet, pwallet), nSleepTime); |
ryanofsky
Feb 27, 2017
Contributor
I super dont like the fact that the pointer to the wallet will end up in debug.log if you have debug=rpc enabled.
Is fixed in later commit c42f3a5 Wallet/RPC: Use filename rather than CWallet pointer, for lockwallet RPCRunLater job name
laanwj
self-assigned this
Mar 2, 2017
|
Great PR. I think we should get this in as soon as possible. |
|
utACK d678771 |
laanwj
merged commit d678771
into
bitcoin:master
Mar 3, 2017
1 check passed
added a commit
that referenced
this pull request
Mar 3, 2017
This was referenced Mar 3, 2017
fanquake
moved this from In progress
to Done
in Multiwallet support
Mar 3, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Mar 7, 2017
|
By the way, I reviewed this partially after merged when rebasing #9845 (making it mostly pointless since most was done here already). |
luke-jr commentedSep 21, 2016
Part of the refactorings needed for basic multiwallet (#8694)