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
Basic multiwallet support #8694
Conversation
MarcoFalke
added
the
Wallet
label
Sep 9, 2016
This was referenced Sep 10, 2016
|
Impressive changeset! Instead of the extending the RPC auth, I could imaging using different RPC endpoints would also work.
bitcoin-cli could just support a new argument Will review soon. |
Indeed, although my main purpose in doing this was to isolate JoinMarket, and it's less isolated if it has auth to my real hotwallet. :) (Also, endpoints seemed like they'd require more code.)
This isn't very future-proof. If we go this route, I'd suggest |
|
Nice, Concept ACK. Will test. |
jonasschnelli
referenced this pull request
Sep 20, 2016
Closed
[Wallet] get rid of pwalletMain, add simple CWallets infrastructure #8764
| @@ -196,8 +196,9 @@ void Shutdown() | ||
| StopRPC(); | ||
| StopHTTPServer(); | ||
| #ifdef ENABLE_WALLET | ||
| - if (pwalletMain) | ||
| - pwalletMain->Flush(false); | ||
| + for (CWallet_ptr pwallet : vpwallets) { |
MarcoFalke
Sep 21, 2016
Member
I like the approach by @jonasschnelli better. Let's keep most of the multiwallet logic in wallet.cpp.
luke-jr
Mar 3, 2017
Member
It's not in wallet.cpp now. Moving it there seems like a good idea, but independent of this PR...
This was referenced Sep 21, 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
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
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Dec 31, 2016
|
Rebased, but please prioritise #8775 review (which this is based on) first. Once that's merged, it may or may not make sense to split the Qt changes out of this. |
|
Concept ACK. Syntax for the auth field should have a clear way to extend it to support a list of wallets (first being the default, I guess). I think. To support things like the path selected wallets suggested above later. |
|
Moved RPC/GUI changes out of this, and rebased. |
|
Rebased and now the next-step in multiwallet integration. |
|
Re-Concept ACK. |
| @@ -31,7 +31,8 @@ | ||
| #include <boost/shared_ptr.hpp> | ||
| #include <boost/thread.hpp> | ||
| -extern CWallet* pwalletMain; | ||
| +typedef CWallet* CWallet_ptr; |
ryanofsky
Mar 6, 2017
Contributor
Curious, why have a CWallet_ptr typedef instead of using CWallet *? Is there a plan to switch to a different type of pointer later? Curious, because this seems to make the rest of the code more opaque. For example:
for (CWallet_ptr pwallet : vpwallets)
Because this says CWallet_ptr instead of CWallet* it's unclear whether the copy initialization has extra cost (which it would for a shared_ptr), implying a const reference should be used instead.
luke-jr
Mar 6, 2017
Member
Indeed, a shared_ptr or similar would be needed for when/if we add the ability to close wallets at runtime.
| - | ||
| - bitdb.mapFileUseCount.erase(_mi++); | ||
| - LogPrint("db", "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart); | ||
| + for (CWallet_ptr pwallet : vpwallets) { |
ryanofsky
Mar 6, 2017
Contributor
This thread is created from the non-static method CWallet::postInitProcess, so it seems like it makes more sense for it to continue flushing a single wallet, rather than going through the global wallets list. Instead of looping and accessing the global vpwallet variable, ThreadFlushWalletDB could just take a new CWallet* pwallet argument and be invoked with:
threadGroup.create_thread([this](){ThreadFlushWalletDB(this);});
from CWallet::postInitProcess.
| } | ||
| + nLastFlushed = CWalletDB::GetUpdateCounter(); |
ryanofsky
Mar 6, 2017
Contributor
How come the nLastFlushed assignment is moving ouside of the _mi != bitdb.mapFileUseCount.end() condition? It seems unrelated to this change. Maybe a code comment explaining the assignment would be good here.
luke-jr
Mar 6, 2017
Member
Because the condition is per-wallet. Maybe nLastFlushed ought to be as well...?
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
|
(needs another rebase) |
laanwj
self-assigned this
Mar 9, 2017
laanwj
added this to the 0.15.0 milestone
Mar 9, 2017
|
Added 0.15.0 milestone. |
|
Significantly rebased. Also fixed minor race conditions surrounding wallet flush (it was bumping the "have update to flush" counter before doing the actual update). |
|
It would be preferable to increment the update counter after committing a database transaction, not after every call to a CWalletDB method. |
| @@ -418,6 +418,7 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue) | ||
| if (mapArgs.count(strArg)) | ||
| return false; | ||
| mapArgs[strArg] = strValue; | ||
| + _mapMultiArgs[strArg].push_back(strValue); |
laanwj
Mar 10, 2017
Owner
I think it is confusing for a "Set" function to add something to a list. If anything it should replace it.
What do you need this for, specifically?
In the past I've defined SoftSetMultiArg to be able to define a whole list argument at once.
luke-jr
Mar 10, 2017
Member
It can't get here unless the list is currently empty. It's used to initialise -wallet, which is accessed as a list only now.
TheBlueMatt
Mar 21, 2017
Contributor
I believe this is also not correct - other threads may be using mapMultiArgs or the vector in it at the same time
luke-jr
Apr 18, 2017
Member
@TheBlueMatt I don't see what your concern is... We have the lock here already.
TheBlueMatt
Apr 27, 2017
Contributor
We do not take the lock when accessing mapMultiArgs all over the codebase. You cannot write a new entry to this map without updating the various locations in the codebase which access mapMultiArgs to also go through cs_args.
| @@ -8,6 +8,8 @@ | ||
| #include "wallet/db.h" | ||
| #include "wallet/wallet.h" | ||
| +CWallet *pwalletMain; |
ryanofsky
Mar 10, 2017
Contributor
In commit "Wallet: Replace pwalletMain with a vector of wallet pointers":
Maybe add a TODO comment for updating the tests to stop referencing pwalletMain, since this will be confusing to someone seeing this who isn't familiar with the pre-multiwallet history of the code.
laanwj
Mar 10, 2017
Owner
Depends on the reason why they are setting pwalletMain. Generally that is to communicate with stuff in wallet.cpp/walletdb.cpp I'd say.
|
I think the overall approach here is good. This is another step towards multi-wallet support. As it's not anywhere on the API yet, I guess it's too early to ask for a multiwallet test? |
IMO too much for this PR. Just trying to multiwallet here, not refactor stuff that doesn't need it. :) |
Maybe my recommendation goes to far but I just think your current approach there is messy. The mutator functions call We need to decide whether CWalletDBStateInfo belongs with the database wrapper, or with the wallet.
|
| @@ -8,6 +8,8 @@ | ||
| #include "wallet/db.h" | ||
| #include "wallet/wallet.h" | ||
| +CWallet *pwalletMain; |
ryanofsky
Mar 10, 2017
Contributor
In commit "Wallet: Replace pwalletMain with a vector of wallet pointers":
Maybe add a TODO comment for updating the tests to stop referencing pwalletMain, since this will be confusing to someone seeing this who isn't familiar with the pre-multiwallet history of the code.
| @@ -32,46 +32,38 @@ static std::atomic<unsigned int> nWalletDBUpdateCounter; | ||
| bool CWalletDB::WriteName(const std::string& strAddress, const std::string& strName) | ||
| { | ||
| - nWalletDBUpdateCounter++; |
ryanofsky
Mar 10, 2017
Contributor
In commit "Bugfix: wallet: Increment "update counter" only after actually making the applicable db changes to avoid potential races":
It seems good not to increment the counter when a write or erase fails. But I don't understand what the "potential races" are that could happen if the counter is incremented regardless. If you could clarify / expand the commit message on this point, I think that would be helpful.
luke-jr
Mar 11, 2017
Member
- (thread 1) Increment the counter.
- (thread 2) DB gets flushed
- (thread 1) Actual change happens.
- (thread 2) Thinks DB hasn't changed, so doesn't flush again.
| @@ -103,42 +94,40 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey, | ||
| Erase(std::make_pair(std::string("key"), vchPubKey)); | ||
| Erase(std::make_pair(std::string("wkey"), vchPubKey)); | ||
| } | ||
| + | ||
| + IncrementUpdateCounter(); |
ryanofsky
Mar 10, 2017
Contributor
In commit "Bugfix: wallet: Increment "update counter" only after actually making the applicable db changes to avoid potential races":
I'm probably missing something, but if the first write above succeeds and second write fails, the counter won't be incremented. Is this wrong? Would a possible fix be to drop this line and replace all the Write/Erases above with WriteIC/EraseIC?
laanwj
Mar 11, 2017
Owner
This is one of the reasons why I suggested above to only update the update counter if a DB transaction actually hits the database. That's more robust than doing it per operation. It's possible for all the operations to succeed then TxnAbort() to be called and still no update happens.
luke-jr
Apr 18, 2017
Member
I agree, but it's outside the scope of this PR. For now, I'll just increment the counter more aggressively (merely reordering the increment to fix the race issue).
|
@laanwj I agree that stuff should be refactored, but I don't think multiwallet needs to depend on it here. (Why is CWalletDB not just a private parent class of CWallet anyway?) |
As said I understand that. I'm not asking for you to do big changes. I just don't want it to become even worse and more muddled. I might pick this up myself if I have some time next week. |
| @@ -256,8 +258,7 @@ void Shutdown() | ||
| #endif | ||
| UnregisterAllValidationInterfaces(); | ||
| #ifdef ENABLE_WALLET | ||
| - delete pwalletMain; | ||
| - pwalletMain = NULL; | ||
| + vpwallets.clear(); |
| @@ -418,6 +418,7 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue) | ||
| if (mapArgs.count(strArg)) | ||
| return false; | ||
| mapArgs[strArg] = strValue; | ||
| + _mapMultiArgs[strArg].push_back(strValue); |
TheBlueMatt
Mar 21, 2017
Contributor
I believe this is also not correct - other threads may be using mapMultiArgs or the vector in it at the same time
| @@ -30,7 +30,8 @@ | ||
| #include <boost/shared_ptr.hpp> | ||
| -extern CWallet* pwalletMain; | ||
| +typedef CWallet* CWallet_ptr; |
laanwj
Apr 12, 2017
Owner
Typedef-ing a pointer type doesn't seem that useful to me either. I suppose the rationale is "what if we want to change it to e.g. std::shared_ptr later". But a) I think the code is more readable if the kind of pointer is clear from the function/struct/class signatures using it b) You might want to have different kinds of pointers to the same kind of objects in different places.
NicolasDorier
Apr 12, 2017
Member
not sure it make sense either, but if it is done, better naming it to CWalletRef to be consistent with CTransactionRef
laanwj
added this to Blockers
in High-priority for review
Mar 24, 2017
| @@ -29,7 +29,8 @@ | ||
| CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) | ||
| { | ||
| - return pwalletMain; | ||
| + // TODO: Some way to access secondary wallets |
NicolasDorier
Apr 12, 2017
•
Member
I throwing an RPC error like RPC_METHOD_NOT_FOUND is better than returning NULL.
luke-jr
Apr 18, 2017
Member
It is not always an error for there to be no wallet (eg, signrawtransaction).
| @@ -3724,24 +3734,17 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) | ||
| bool CWallet::InitLoadWallet() | ||
| { | ||
| if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { | ||
| - pwalletMain = NULL; |
NicolasDorier
Apr 12, 2017
•
Member
vpwallets.clear() ?
EDIT: Meh, not really needed, just thought it would be more coherent.
|
not blocking, but I think a It would impact:
That said, this can be done in a separate PR. |
| @@ -29,7 +29,8 @@ | ||
| CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) | ||
| { | ||
| - return pwalletMain; | ||
| + // TODO: Some way to access secondary wallets | ||
| + return vpwallets.empty() ? NULL : vpwallets[0]; |
| - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) | ||
| - return InitError(strError); | ||
| + for (const std::string& walletFile : mapMultiArgs.at("-wallet")) { | ||
| + if (walletFile.find_first_of("/\\") != std::string::npos) { |
laanwj
Apr 12, 2017
Owner
walletFile.find_first_of("/\\") is not portable. Likely, boost::filesystem::path has a way to check a path for path separators.
luke-jr
Apr 18, 2017
Member
boost::filesystem::path walletFileBoost = walletFile;
if (walletFileBoost.has_root_path() || walletFileBoost.has_parent_path()) {This would work, but off-topic here since this is existing code.
|
In-scope nits addressed and rebased. |
| @@ -484,6 +485,8 @@ void ForceSetArg(const std::string& strArg, const std::string& strValue) | ||
| { | ||
| LOCK(cs_args); | ||
| mapArgs[strArg] = strValue; | ||
| + _mapMultiArgs[strArg].clear(); |
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Apr 21, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Apr 21, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Apr 21, 2017
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Apr 21, 2017
sipa
removed this from Blockers
in High-priority for review
May 4, 2017
|
Rebased |
ryanofsky
reviewed
May 22, 2017
utACK 68bc5b9. This is much simpler than before and the bugfixes and cleanup are nice even independent of the multiwallet changes.
| @@ -122,11 +122,15 @@ class CWalletDBWrapper | ||
| void IncrementUpdateCounter(); | ||
| unsigned int GetUpdateCounter(); | ||
| + std::atomic<unsigned int> nUpdateCounter; | ||
| + unsigned int nLastSeen; |
ryanofsky
May 22, 2017
Contributor
In commit "Wallet: Replace pwalletMain with a vector of wallet pointers"
Should initialize these values.
ryanofsky
Jun 6, 2017
Contributor
Should initialize these values.
Note: comment no longer applies. This is now done in two CWalletDBWrapper constructors.
| + std::atomic<unsigned int> nUpdateCounter; | ||
| + unsigned int nLastSeen; | ||
| + unsigned int nLastFlushed; | ||
| + int64_t nLastWalletUpdate; |
ryanofsky
May 22, 2017
Contributor
In commit "Wallet: Replace pwalletMain with a vector of wallet pointers"
It would be nice if conversion of these values from static variables to per-wallet members happened in the previous commit ("CWalletDB: Store the update counter per wallet") instead of this one. Would make both commits easier to follow and avoid the unusual intermediate state where globals and per-wallet members are compared to each other.
| private: | ||
| /** BerkeleyDB specific */ | ||
| CDBEnv *env; | ||
| std::string strFile; | ||
| + std::atomic<unsigned int> nUpdateCounter; |
ryanofsky
May 22, 2017
Contributor
In commit "CWalletDB: Store the update counter per wallet":
Should initialize this value.
ryanofsky
Jun 5, 2017
Contributor
It's an atomic, should have a default constructor?
Yes but it seems to not initialize the value, see
https://stackoverflow.com/questions/36320008/whats-the-default-value-for-a-stdatomic or http://en.cppreference.com/w/cpp/atomic/atomic/atomic. IMO, adding = 0 to this line would make the code clearer anyway.
| @@ -762,20 +760,22 @@ void MaybeCompactWalletDB() | ||
| return; | ||
| } | ||
| - static unsigned int nLastSeen = CWalletDB::GetUpdateCounter(); | ||
| - static unsigned int nLastFlushed = CWalletDB::GetUpdateCounter(); | ||
| + CWalletDBWrapper& dbh = pwalletMain->GetDBHandle(); |
ryanofsky
May 22, 2017
Contributor
In commit "CWalletDB: Store the update counter per wallet"
Maybe call this dbw for consistency with existing wallet code.
| + if (!batch.Write(key, value, fOverwrite)) { | ||
| + return false; | ||
| + } | ||
| + IncrementUpdateCounter(); |
ryanofsky
May 22, 2017
Contributor
In commit "Bugfix: wallet: Increment "update counter" only after actually making the applicable db changes to avoid potential races"
Would be helpful to have a comment mentioning that counter should be updated after the write operation, rather than before to prevent a race where the flush thread could run and store the higher counter value before the database is fully updated.
Could also mention the idea of moving the counter increment to the destructor / commit function so these write and erase wrappers would be unnecessary.
| @@ -247,6 +245,7 @@ class CWalletDB | ||
| bool WriteVersion(int nVersion); | ||
| private: | ||
| CDB batch; | ||
| + CWalletDBWrapper& wrapper; |
ryanofsky
May 22, 2017
Contributor
In commit "CWalletDB: Store the update counter per wallet"
Might be nice to call this member dbw instead of wrapper for consistency with the wallet member.
| - CWallet dummyWallet; | ||
| - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) | ||
| + std::string strError; | ||
| + if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) |
jonasschnelli
May 24, 2017
Member
This redundantly opens/checks the datadir via BDB. Not sure if this is a problem...
| - static unsigned int nLastSeen = CWalletDB::GetUpdateCounter(); | ||
| - static unsigned int nLastFlushed = CWalletDB::GetUpdateCounter(); | ||
| - static int64_t nLastWalletUpdate = GetTime(); | ||
| + for (CWalletRef pwallet : vpwallets) { |
| @@ -440,30 +440,40 @@ bool CWallet::Verify() | ||
| if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) | ||
| return true; | ||
| + SoftSetArg("-wallet", DEFAULT_WALLET_DAT); | ||
| + | ||
| uiInterface.InitMessage(_("Verifying wallet...")); |
| + { | ||
| + // Recover readable keypairs: | ||
| + CWallet dummyWallet; | ||
| + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) |
jonasschnelli
May 24, 2017
Member
This renames an arbitrary wallet name to "wallet.%d.bak", collisions may happen.
2017-05-24 07:56:04 Renamed test1.dat to wallet.1495612559.bak
jonasschnelli
May 24, 2017
Member
Maybe we should use <filename>.<date>.bak (will result in something like test1.dat.1495612559.bak (which is preferable IMO).
jnewbery
May 29, 2017
Member
I agree with @jonasschnelli . This seems dangerous if Recover() or VerifyDatabaseFile() is called for multiple wallets. Should be straightforward to update Recover() to name the backup file uniquely (the warning string in VerifyDatabaseFile() will also need to be updated)
|
Tested a bit and seems to work as intended. Conceptual:This PR mostly goes into a direction that one has to choose the wallets-to-work-with before starting up Core. I miss the pre-work for run-time adding and removing of wallets. Sure, this may be added later.
|
|
Gitian builds are failing (all three platforms): https://bitcoin.jonasschnelli.ch/build/147 |
These should probably become less visible or go away or move to a separate utility.
We can do this from the rpc now. Not sure about upgradewallet. |
jonasschnelli
referenced this pull request
May 26, 2017
Closed
Don't use fixed "wallet.bak"-filename during salvagewallet #10457
jnewbery
reviewed
May 29, 2017
A couple of small nits inline, and a couple of general comments:
- I think this could do with both unit and integration tests
- Please update the comment for
CWallet::Verify()in wallet.h now that it's responsible for parsing the wallet arguments and populating the ArgsManager
| + ++nUpdateCounter; | ||
| +} | ||
| + | ||
| +unsigned int CWalletDBWrapper::GetUpdateCounter() |
jnewbery
May 29, 2017
Member
You've changed MaybeCompactWalletDB() to access CDB::nUpdateCounter directly, so this function isn't used.
| + { | ||
| + // Recover readable keypairs: | ||
| + CWallet dummyWallet; | ||
| + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) |
jnewbery
May 29, 2017
Member
I agree with @jonasschnelli . This seems dangerous if Recover() or VerifyDatabaseFile() is called for multiple wallets. Should be straightforward to update Recover() to name the backup file uniquely (the warning string in VerifyDatabaseFile() will also need to be updated)
| - nWalletDBUpdateCounter++; | ||
| - | ||
| - if (!batch.Write(std::make_pair(std::string("keymeta"), vchPubKey), | ||
| + if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), |
jnewbery
May 29, 2017
Member
Please update to use braces. You can also combine this line with the one below.
Several other if statements below which you can update to use braces.
luke-jr
added some commits
Jan 3, 2017
|
Rebased and issues addressed |
|
Travis falure:
|
The importwallet_rescan test has another pwalletMain usage that needs to be changed to vpwallets. |
ryanofsky
reviewed
Jun 6, 2017
utACK 33f0b60 with the test fix. First 6 commits were basically unchanged since my previous review (just a member rename and atomic init fixes). 7 new commits have been added and seem fine.
| @@ -439,11 +439,6 @@ void CWalletDBWrapper::IncrementUpdateCounter() | ||
| ++nUpdateCounter; | ||
| } | ||
| -unsigned int CWalletDBWrapper::GetUpdateCounter() |
ryanofsky
Jun 6, 2017
Contributor
In commit "Wallet: Support loading multiple wallets if -wallet used more than once"
Removing GetUpdateCounter in this commit isn't related to the rest of the changes here. This change was probably meant for the "CWalletDB: Store the update counter per wallet" commit.
| @@ -122,11 +122,15 @@ class CWalletDBWrapper | ||
| void IncrementUpdateCounter(); | ||
| unsigned int GetUpdateCounter(); | ||
| + std::atomic<unsigned int> nUpdateCounter; | ||
| + unsigned int nLastSeen; |
ryanofsky
Jun 6, 2017
Contributor
Should initialize these values.
Note: comment no longer applies. This is now done in two CWalletDBWrapper constructors.
| @@ -19,6 +19,8 @@ | ||
| #include <boost/test/unit_test.hpp> | ||
| #include <univalue.h> | ||
| +extern CWallet* pwalletMain; |
ryanofsky
Jun 6, 2017
Contributor
In commit "Replace pwalletMain with a vector of wallet"
This can probably be removed after the importwallet_rescan test is updated.
ryanofsky
Jun 9, 2017
Contributor
This can probably be removed after the importwallet_rescan test is updated.
Never mind, it's used by the receiverequests test.
| @@ -440,30 +440,40 @@ bool CWallet::Verify() | ||
| if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) | ||
| return true; | ||
| - uiInterface.InitMessage(_("Verifying wallet...")); | ||
| - std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); | ||
| + SoftSetArg("-wallet", DEFAULT_WALLET_DAT); |
ryanofsky
Jun 6, 2017
Contributor
In commit "Wallet: Move multiwallet sanity checks to CWallet::Verify"
Consider squashing this commit into previous commit "Wallet: Support loading multiple wallets if -wallet used more than once", because the two commits are making parallel sets changes, and having them separate makes the interaction confusing to think about.
| @@ -825,7 +825,7 @@ bool CWalletDB::VerifyEnvironment(const std::string& walletFile, const fs::path& | ||
| bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr) | ||
| { | ||
| - return CDB::VerifyDatabaseFile(walletFile, dataDir, errorStr, warningStr, CWalletDB::Recover); | ||
| + return CDB::VerifyDatabaseFile(walletFile, dataDir, warningStr, errorStr, CWalletDB::Recover); |
ryanofsky
Jun 6, 2017
Contributor
In commit "Bugfix: wallet: Fix warningStr, errorStr argument order"
Note: the bug seems to have been introduced in #8574.
|
I've had a quick scan and the new commits look generally good, although #10457 seems like a simpler solution to the wallet backup name issue. I don't think it's really worth passing the backup file name around through multiple function calls just so it can be printed in a single warning message. I'll fully review once the the test has been fixed. |
luke-jr
added some commits
Sep 9, 2016
| @@ -3972,15 +3979,27 @@ bool CWallet::ParameterInteraction() | ||
| } | ||
| if (GetBoolArg("-salvagewallet", false) && SoftSetBoolArg("-rescan", true)) { | ||
| + if (is_multiwallet) { | ||
| + return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); |
achow101
Jun 7, 2017
Member
Here you say that -salvagewallet is only for one wallet file, but in CWallet::Verify(), the loop through all wallets checks for -salvagewallet and recovers all wallets if -salvagewallet is set. Which behavior is correct: salvage all wallets, or salvage only if there is one wallet?
For the latter, the -salvagewallet check in CWallet::Verify() can be moved out of the loop.
luke-jr
Jun 7, 2017
Member
Both are correct. If we get to ::Verify, we should salvage all wallets. But for now, we forbid this combination. Moving it out of the loop is error-prone, and creates unnecessary complexity.
ryanofsky
reviewed
Jun 9, 2017
utACK c237bd7. Changes since previous review were fixing rescan test, updating a salvagewallet comment, and removing GetUpdateCounter in an earlier commit.
| @@ -19,6 +19,8 @@ | ||
| #include <boost/test/unit_test.hpp> | ||
| #include <univalue.h> | ||
| +extern CWallet* pwalletMain; |
ryanofsky
Jun 9, 2017
Contributor
This can probably be removed after the importwallet_rescan test is updated.
Never mind, it's used by the receiverequests test.
|
utACK c237bd7 |
laanwj
merged commit c237bd7
into
bitcoin:master
Jun 12, 2017
1 check passed
added a commit
that referenced
this pull request
Jun 12, 2017
fanquake
moved this from In progress
to Done
in Multiwallet support
Jun 12, 2017
I agree. We should probably revert that part and do #10457 afterward. |
luke-jr commentedSep 9, 2016
•
Edited 1 time
-
luke-jr
Sep 9, 2016
This allows running with multiple -wallet options to load more than one wallet.
GUI has independent comboboxen for the main GUI window and debug console to select which wallet to view/use. The comboboxes are not visible in the main GUI unless multiple wallets are loaded (the debug window's combobox is useful even for a single wallet, since it allows selecting "(none)" to block wallet access).RPC can access only one wallet per user, but rpcauth is extended to accept a 4th field which controls which wallet, if any, the user has access to. I chose to do it this way because pre-multiwallet nodes will gracefully ignore such rpcauth rather than expose their wallet. The field can also be a single hyphen to block wallet access.(RPC and GUI changes are moved to my
multiwallet_rpcandmultiwallet_guibranches)