Dynamically Loadable Multiple Wallet Support Complete!!! #2124

pull CodeShark wants to merge 38 commits into bitcoin:master from CodeShark:multiwallet changing 28 files +1407 −525
  1. CodeShark commented at 1:30 pm on December 23, 2012: contributor

    bitcoind now supports loading more than one wallet at once.

    A singleton object of type CWalletManager now exists. It handles dynamic loading/unloading and synchronization of wallets and allows different parts of the application to access wallets by name.

    A new CWallet* parameter has been added to the RPC functions. Functions which do not use a wallet simply ignore it. In addition, a new field has been added to CRPCCommand that tells us whether or not the function can be called on a wallet.

    Wallet-specific information has been removed from RPC method getinfo. Instead, getinfo just reports how many wallets are currently loaded. Detailed wallet info is now available via the listwallets method.

    Four new RPC methods have been added:

    • listwallets Returns an array containing wallet information.
    • usewallet [params] Allows you to apply existing RPC commands to different wallets. A default wallet named the empty string is always loaded and is used if calls are made without usewallet. Example: bitcoind usewallet foo listreceivedbyaddress 0 true (thanks, gmaxwell, for the idea)
    • loadwallet [rescan=false] [upgradewallet=false] [maxversion=(latest)] Dynamically loads an existing wallet file wallet-.dat. If no wallet file exists a new wallet is created. The default wallet file is always called wallet.dat.
    • unloadwallet

    To specify additional wallets at startup, use option -usewallet=foo -usewallet=bar etc…as detailed here: #2124 (comment) and https://github.com/CodeShark/bitcoin/commit/9d201cfaf9f54042ec0ff8265cd2201545568b6d

    TODO:

    • Clean up I/O in CWalletManager::LoadWallet - debug, error, and UI output functions.
    • Check synchronization code.
    • Test mining functionality. Allow RPC mining on arbitrary wallets.
    • Integrate with Qt.
  2. CodeShark commented at 1:39 pm on December 23, 2012: contributor
    It’s a work in progress and can certainly be improved. I welcome all comments, suggestions, criticisms, and witty insults.
  3. Diapolo commented at 1:59 pm on December 23, 2012: none
    Would it be better or possible to use references instead of pointers in your code?
  4. CodeShark commented at 2:41 pm on December 23, 2012: contributor
    Possible, sure. Better, why?
  5. CodeShark commented at 2:44 pm on December 23, 2012: contributor

    The sanity test failed because the test suite uses the old RPC function prototype. I was still able to build and run using

    • make -f makefile.unix bitcoind
  6. rebroad commented at 2:52 pm on December 23, 2012: contributor
    This may be an opportunity to move away from the wallets being called “wallet.dat”, which makes it all the more easier for malware to steal the contents.
  7. CodeShark commented at 3:48 am on December 24, 2012: contributor

    You can now specify additional wallets in the config file or via command line arguments:

    0usewallet=foo
    

    or

    0bitcoind -usewallet=foo
    

    A default wallet called "" in the RPC and using file “wallet.dat” is always loaded, as to not break compatibility with the master branch. Therefore, additional wallets should neither be called “default” nor “wallet”.

    The wallet will be stored in a file called wallet-foo.dat. If the wallet doesn’t yet exist, it will be created the first time the wallet is loaded.

  8. Added multiple wallet support
    =============================
    
    A new global structure called pWalletMap has been added. Upon initialization, multiple wallets can be loaded.
    
    A new CWallet* parameter has been added to the RPC functions. Functions which do not use a wallet simply ignore it. In addition, a new field has been added to CRPCCommand that tells us whether or not the function uses a wallet.
    
    Two new RPC methods have been added:
      1) listwallets - Returns an array containing wallet names.
      2) usewallet - Prefix existing wallet RPC calls with usewallet <walletname> to use a particular wallet. If no wallet is specified, the default wallet is used.
        example: bitcoind usewallet foo listreceivedbyaddress 0 true
    
    TODO:
      1) Get wallet names from bitcoin.conf in init.cpp.
      2) Change help RPC so that the message does not depend on wallet state (i.e. walletpassphrase RPC call)
    71c63e3636
  9. Added CWallet* parameter to RPC test suite and a CWalletMap instance to test_bitcoin.cpp 4a6b0e290b
  10. Fixed RPC issues detected by test suite. 158ce39274
  11. Added loading of wallet names and files from -usewallet arguments
    =================================================================
    
    You can now specify additional wallets in the config file or via command line arguments:
    
    	usewallet=foo
    
    or
    
    	bitcoind -usewallet=foo
    
    A default wallet called "default" in the RPC and using file "wallet.dat" is always loaded, as to not break compatibility with the master branch. Therefore, additional wallets should neither be called "default" nor "wallet" nor anything else that might conflict with other filenames in the .bitcoin directory.
    
    The wallet will be stored in a file called foo.dat. If the wallet doesn't yet exist, it will be created the first time bitcoind is run.
    
    TODO: Ensure filename collisions cannot occur. Perhaps allow the wallet files to be arbitrarily named rather than tied to their identifier.
    1b640c143f
  12. TxMemPool::accept() calls SyncWithWallets(), so all mempool transactions are synched automatically without having to call SyncWithWallets() explicitly. This is important when sending between two wallets in a single bitcoind instance so that the receiving wallet is alerted of the transaction immediately.
    Removed calls to SyncWithWallets() in ProcessMessage() since SyncWithWallets() is already called by tx.AcceptToMemoryPool().
    
    SyncWithWallets() is still called explicitly from CBlock::ConnectBlock() since the transaction never goes through the mempool in this case.
    1cdf18b85b
  13. Modified getinfo RPC call to return an array of wallets 27fa196cb8
  14. Removed dependency on wallet encryption state for getting help on RPC methods. Help always returns usage info now. 93e6b809eb
  15. usewallet now checks whether method is valid. 0f815bf909
  16. CodeShark commented at 5:14 pm on December 24, 2012: contributor
    The getinfo RPC method now returns an array of wallets each with wallet-specific information. This change is, unfortunately, not backwards compatible. However, it doesn’t really seem to make sense to make this call wallet-specific. And returning an array of wallets seems to be a very useful feature.
  17. gmaxwell commented at 7:13 pm on December 24, 2012: contributor
    An alternative would be to move that data out of getinfo and into a getwallet info. Part of the reason to do that is that the wallet outputs in getinfo can be rather slow already, and doing them for N wallets won’t help matters. (Though lets see if anyone else has an opinion, I could be on drugs here)
  18. CodeShark commented at 7:20 pm on December 24, 2012: contributor
    I was thinking listwallets should maybe show all this information with a verbose option. Without the verbose option, it would just give a list of the wallet names.
  19. gmaxwell commented at 8:03 pm on December 24, 2012: contributor
    Hm. From the perspective of the RPC as a CLI the use of verbose flags isn’t especially discoverable— for something basic like ‘get your balances’ that is probably worth exposing at the top level. ::shrugs::
  20. CodeShark commented at 8:10 pm on December 24, 2012: contributor
    What about making the full info the default and having an option to shorten it? That way interactive users get relevant information while application developers seeking to improve performance have an option to do so if they don’t need all that information. Of course we can just have two distinct RPC methods…but I’d rather avoid having too many RPC calls when the semantics are similar.
  21. CodeShark commented at 8:14 pm on December 24, 2012: contributor

    I do think that the wallet information should be completely removed from getinfo, though.

    Anyhow, this is the kind of stuff that’s really easy to implement and change up front but becomes a serious problem to change once people start using it to build applications. I’d also like to hear several more opinions on this before committing to anything specific.

  22. CodeShark commented at 8:38 pm on December 24, 2012: contributor
    Another issue I’m wondering about is programmatic access to the config file. We could just append the new wallets to the end of the file whenever they are created - but it would be nice to be able to have tags for sections. Presumably whenever a user creates a new wallet they want it to be loaded at next startup unless they explicitly remove it from the config file.
  23. mikegogulski commented at 0:14 am on December 25, 2012: none

    Multiple wallet support came into my head as I was doing #2075 but I left it aside in favor of trying to move the code in the direction of further modularization improvements between the RPC interface and the wallet and the wallet database as a prerequisite. I put off coding there since I expected something like this to come along and because commentary on the pull request died away.

    I can’t review the code in detail now but this capability needs to happen. Passing CWallet * around is an improvement for sure, definitely better than another global. I’m finding it kinda cringeworth-brittle from an OO perspective, though. It would be lovely to see new RPC functions implemented in ways that drag suitable amounts of code that depends strongly on the wallet’s internal representation out along with them the appropriate changes to the wallet object.

    Have you tried merging my code? I’ll have to look at that later. Multiple wallets are useful for any number of reasons. Certainly the Bitcoin-only accountants and would-be tax collectors of the future aren’t going to be running n instances of bitcoind on their desktops.

    Ultimate I think the wallet should be decoupled from the rest of the satoshi client. Pushing standarized interfaces down to wallet-object level is somewhere on the road to getting there. You seem to be addressing some modularization issues in other areas though, too.

  24. CodeShark commented at 5:36 am on December 25, 2012: contributor

    As for the OO stuff, I would like to abstract things further and define a listener interface, a transaction store interface, and a key store interface. Technically speaking, a signing agent doesn’t even need to store complete transactions. Private keys and unspent outpoints are all it needs. Furthermore, a listening agent could send alerts to other components without the need to store any transactions. For instance, it could just provide filtering.

    Having said that, in the interest of seeing these pull requests merged with bitcoin/bitcoin master ASAP, I’m willing to do things incrementally and use whatever structures already exist for now. However, I’d be very interested in giving all this some deeper thought and coming up with a serious reorganization for some later version.

    As for now, at the very least it is possible to encapsulate the existing CWallet class much better - and I applaud your efforts.

  25. in src/bitcoinrpc.cpp: in 0f815bf909 outdated
    1078-                result = pcmd->actor(params, false);
    1079+            if (pcmd->unlocked) {
    1080+                result = pcmd->actor(pWallet, params, false);
    1081+            }
    1082             else {
    1083                 LOCK2(cs_main, pwalletMain->cs_wallet);
    


    sipa commented at 5:34 pm on December 25, 2012:
    This will need to lock the appropriate wallet (if any), not pwalletMain.
  26. in src/init.cpp: in 0f815bf909 outdated
    24@@ -25,6 +25,7 @@
    25 using namespace std;
    26 using namespace boost;
    27 
    28+CWalletMap* pWalletMap;
    


    sipa commented at 5:35 pm on December 25, 2012:
    pWalletMap can be allocated statically, I believe.

    CodeShark commented at 9:37 pm on December 25, 2012:
    A problem is that it is declared in both init.cpp and test_bitcoin.cpp - and these globals must be accessible from rpcwallet.cpp as well, which includes init.h for the externs. I would prefer the wallet RPC calls to be placed in an RPC class which takes a wallet map in its constructor - and then we could remove any dependencies on these externs entirely and restrict the variable scope to init.cpp or the unit test main. But yeah, it could be allocated statically.
  27. in src/wallet.h: in 0f815bf909 outdated
    317+class CWalletMap
    318+{
    319+public:
    320+    wallet_map wallets;
    321+
    322+    ~CWalletMap()
    


    sipa commented at 5:36 pm on December 25, 2012:
    You may want to use an auto_ptr to make this cleanup happen automatically.

    CodeShark commented at 9:41 pm on December 25, 2012:

    I was thinking to expand this class to also handle loading of wallets from config parameters.

    Perhaps init.cpp could pass io context stuff to the loader method so that the loader method needn’t call printf directly.

  28. sipa commented at 5:48 pm on December 25, 2012: member

    In general: I’m very much in favor of having native support for multiple wallets. Wallet stuff hasn’t been a priority for some time, but if necessary I’d like to help to get this working.

    Regarding the idea of separating wallets for block chain processing: sure, that’s definitely where we need to go in the future. Ideally, I think the code evolves to separate wallet and the rest along a clean interface in a first step indeed. In a second step, we can maybe make them separate processes started from the same binary or even just separate binaries with shared codebase. The final aim should be entirely separate things, either communicating via some private “wallet interconnect protocol” (where several wallets on a trusted network connect to a single validation service), or even turning the wallet processes into standalone SPV clients (with their own blockheader-chain), that can either connect directly to the network, or can connect to a server provide block/tx validation service, simply via the P2P protocol.

  29. Fixed LOCK to lock appropriate wallet. 924f088620
  30. Fixed wallet load time indicator. fa1c80863d
  31. mikegogulski commented at 9:14 pm on December 25, 2012: none
    On the wallet site of things, IMHO, we could think about switching the interface to JSON-RPC for all interaction with the wallet object(s) and database(s), which would eventually enable bitcoin-qt to talk to wallets on report machines over SSL/TLS. That’s painful to tackle all at once, though, since there’s plenty of code outside the RPC bundle right now that depends on wallet internals and a while lot of methods sticking off of CWallet.
  32. rebroad commented at 10:03 pm on December 25, 2012: contributor
    This pull request is confusing me as it’s raised by a different user to the user making the commits.. (or maybe I don’t understand github correctly). Also, I’m wondering if such a thing as a “roadmap” exists for bitcoind/bitcoin-qt. I’m thinking that perhaps the project could be split into two binaries, one that deals with the P2P stuff and sending/receiving tx/blocks, and the other that deals with purely wallet stuff. Currently bitcoind is slowly becoming bloated with both, and a focus on making the split possible might be useful.
  33. CodeShark commented at 10:09 pm on December 25, 2012: contributor
    Both users are me. I don’t use my CodeShark identity for pushes, though. CodeShark is reserved for github.
  34. Moved wallet detail information out of getinfo and put it in listwallets. getinfo now just shows how many wallets are loaded. b0cae87871
  35. Moved code for locking a wallet automatically at a certain time from rpcwallet.cpp into CCryptoKeyStore class.
    TODO:
      Encapsulate the thread spawning and make the call nonblocking.
      Give each thread a unique name.
    2b31fdfef9
  36. Dynamic loading and unloading of wallets.
    New Changes:
      - Moved LoadWallet out of init.cpp and into CWalletMap class.
      - Added new RPC methods: loadwallet and unloadwallet.
    
    TODO:
      - Clean up I/O in CWalletMap::LoadWallet - debug, error, and UI output functions.
      - Make sure wallet loading and unloading are thread-safe.
      - Save wallets to bitcoin.conf automatically.
    1b51a7f7bd
  37. New naming scheme for wallets. Checks for valid character set. CWalletMap now handles unregistration of wallets from main.
    Added linker option to makefiles for boost_regex.
    3fd110a6f7
  38. More load options at startup.
    If at least one -usewallet parameter is given, it will use those parameters to determine which wallets to load at startup.
    If no -usewallet parameters are given, it searches the data directory for files named wallet-<walletname>.dat.
    
    Also added -nousewallet parameters which override either -usewallet or the data directory.
    9d201cfaf9
  39. CodeShark commented at 4:54 pm on December 27, 2012: contributor
    Dynamic wallet loading is essentially complete. An important issue that needs to be resolved prior to any integration is making sure its use of LOCKs on threads is ok. Error handling on initialization is also not super smooth, but that’s more an issue with AppInit2 generally. At this point I mostly just want to polish up what’s there, fix any potential bugs or serious issues, leave this branch alone, and go work on other features.
  40. Thread-safe CWalletMap. 2256d1d7f7
  41. Using GetWallet instead of pWalletMap->wallets.find 3f5d692883
  42. Using GetWallet instead of pWalletMap->wallets.find 629ca2fc5c
  43. Merge branch 'multiwallet' of 108.60.150.142:../gitrepos/bitcoin into multiwallet 55d301c7f7
  44. Moved RPC type conversion for usewallet to RPCConvertValues function. ebf85b17aa
  45. Fixed usewallet params. 74228a2228
  46. Added preprocessor directive for boost filesystem v2 vs v3. ec0cc4bfcb
  47. Better encapsulation on WalletMap class, moved critical section locks to within the class methods themselves and out of bitcoinrpc.cpp, wallet unload locks on individual wallet rather than all wallets. 7348f78bc7
  48. Checking for CDB exceptions upon loading wallet. d21a960ef4
  49. Added unload methods for wallet db and call to unload in ~CWallet(). f409a6d413
  50. Fixed test_bitcoin issue. 6215e532f0
  51. Added locks on setpwalletRegistered functions. d8b0cf104d
  52. Added ReacceptWalletTransactions() registered wallet function in main rather than iterating through the wallet map in init. 3d15116f3c
  53. in src/bitcoinrpc.cpp: in 2256d1d7f7 outdated
    1068@@ -1065,16 +1069,20 @@ void ThreadRPCServer3(void* parg)
    1069         !pcmd->okSafeMode)
    1070         throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
    1071 
    1072+    if (!pWallet) pWallet = pwalletMain;
    


    CodeShark commented at 9:19 pm on December 29, 2012:
    Probably should use pWalletMap->GetDefaultWallet() wherever pwalletMain appears anywhere in the application.
  54. in src/rpcwallet.cpp: in 2256d1d7f7 outdated
    1567+        throw runtime_error(
    1568+            "usewallet <walletname> <method> [params]\n"
    1569+            "Selects which wallet to use.");
    1570+    
    1571+    string strWalletName = params[0].get_str();
    1572+    wallet_map::iterator it = pWalletMap->wallets.find(strWalletName);
    


    CodeShark commented at 9:44 pm on December 29, 2012:
    Should use pWalletMap->GetWallet(strWalletMap);
  55. in src/rpcwallet.cpp: in 629ca2fc5c outdated
    1544+        throw runtime_error(
    1545+            "listwallets\n"
    1546+            "Returns list of wallets.");
    1547+    
    1548+    Object obj;
    1549+    BOOST_FOREACH(const wallet_map::value_type& item, pWalletMap->wallets)
    


    CodeShark commented at 10:22 pm on December 29, 2012:
    I would prefer not to have to access pWalletMap->wallets directly…but using BOOST_FOREACH like this is quite convenient.

    sipa commented at 1:02 am on January 6, 2013:
    You can implement an iterator for CWalletMap, if you really want BOOST_FOREACH.
  56. in src/bitcoinrpc.cpp: in 629ca2fc5c outdated
    1076         // Execute
    1077         Value result;
    1078         {
    1079-            if (pcmd->unlocked)
    1080-                result = pcmd->actor(params, false);
    1081+            LOCK(pWalletMap->cs_WalletMap);
    


    sipa commented at 0:55 am on January 6, 2013:
    I don’t think you want to keep the walletmap locked during the actual RPC execution.

    CodeShark commented at 7:50 am on January 7, 2013:
    Totally agreed - this was just me being extra cautious until the locking issues can be further looked into.
  57. in src/bitcoinrpc.cpp: in 629ca2fc5c outdated
    1227@@ -1220,6 +1228,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
    1228     if (strMethod == "lockunspent"            && n > 0) ConvertTo<bool>(params[0]);
    1229     if (strMethod == "lockunspent"            && n > 1) ConvertTo<Array>(params[1]);
    1230     if (strMethod == "importprivkey"          && n > 2) ConvertTo<bool>(params[2]);
    1231+    if (strMethod == "loadwallet"             && n > 1) ConvertTo<bool>(params[1]);
    1232+    if (strMethod == "loadwallet"             && n > 2) ConvertTo<bool>(params[2]);
    1233+    if (strMethod == "loadwallet"             && n > 3) ConvertTo<boost::int64_t>(params[3]);
    


    sipa commented at 0:56 am on January 6, 2013:
    Doesn’t RPCConvertValues need some magic to deal with usewallet?

    CodeShark commented at 7:55 am on January 7, 2013:

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

    Now RPCConvertValues does the magic.

  58. in src/keystore.cpp: in 629ca2fc5c outdated
    83@@ -84,9 +84,48 @@ bool CCryptoKeyStore::Lock()
    84     }
    85 
    86     NotifyStatusChanged(this);
    87+    nLockTime = 0;
    88+        
    89     return true;
    90 }
    91 
    92+void CCryptoKeyStore::SleepThenLock(int64 nMyWakeTime)
    


    sipa commented at 0:59 am on January 6, 2013:
    What is this? Seems unrelated to the pull request…

    CodeShark commented at 9:47 am on January 10, 2013:
    The reason this was added was because we need to be able to unlock each wallet individually. The RPC methods shouldn’t have to be keeping track of when it’s time to lock the wallet again, so the options seem to be to either move the timer to within the CCryptoKeyStore class itself - or to write a helper class that manages this.
  59. in src/util.cpp: in 629ca2fc5c outdated
    956+    if (!boost::filesystem::exists(_path))
    957+        throw runtime_error("Path does not exist.");
    958+    
    959+    if ((flags & file_option_flags::REGULAR_FILES) && boost::filesystem::is_regular_file(_path))
    960+    {
    961+        vstrFiles.push_back(_path.filename().string());
    


    sipa commented at 1:04 am on January 6, 2013:
    Just use _path.string().

    CodeShark commented at 7:56 am on January 7, 2013:
    Won’t that return the complete path including directories? I just want the filenames.

    sipa commented at 12:12 pm on January 7, 2013:
    Oh, yes - you’ll need compatibility with boost filesystem v2 though… for now
  60. in src/wallet.h: in 629ca2fc5c outdated
    319+const boost::regex WALLET_FILE_REGEX("wallet-([a-zA-Z0-9_]+)\\.dat");
    320+typedef std::map<std::string, CWallet*> wallet_map;
    321+class CWalletMap
    322+{
    323+public:
    324+    mutable CCriticalSection cs_WalletMap;
    


    sipa commented at 1:08 am on January 6, 2013:
    Is there an actual need for this critsect to be exposed publically? Ideally (and I know a lot of old code offends against this horribly), critical sections are private and only taken by class methods itself.

    CodeShark commented at 7:30 am on January 10, 2013:

    so the preferred style would be something like a lock method containing LOCK(cs_WalletMap)? I guess that wouldn’t work because it would go out of scope when the method returns.

    So could you give a quick example of the style?


    CodeShark commented at 7:36 am on January 10, 2013:
    Actually, the only locking really needed is when unloading wallets. The rest of the wallet locking could be handled by the wallet class itself. So it seems an even better solution is to just lock on the wallet inside the UnloadWallet method. I’m wondering whether we should be locking on the UnregisterWallet method in main…Btw, is the std::map class thread-safe? Are inserts, deletes, and searches atomic?
  61. in src/makefile.unix: in f409a6d413 outdated
    31@@ -32,6 +32,7 @@ LIBS += \
    32    -l boost_filesystem$(BOOST_LIB_SUFFIX) \
    33    -l boost_program_options$(BOOST_LIB_SUFFIX) \
    34    -l boost_thread$(BOOST_LIB_SUFFIX) \
    35+   -l boost_regex$(BOOST_LIB_SUFFIX) \
    


    CodeShark commented at 11:55 am on January 10, 2013:
    This is what’s causing BitcoinPullTester to fail. Could we add this library?

    Diapolo commented at 12:55 pm on January 10, 2013:
    Is Boost Regex a compiled lib or does it consist only of a .hpp file? If you need it for this pull to work you will also need to add it to bitcoin-qt.pro for the Qt client to work.

    gavinandresen commented at 3:42 pm on January 10, 2013:

    If I recall correctly, boost::regex can be used either as headers-only OR requires-linking. Downside of headers-only is it increases compile times and uses a lot more memory when compiling.

    It seems odd that the build testing machine would have boost built without the regex library, I thought the regexp library was built by default when you built boost.


    CodeShark commented at 5:32 pm on January 10, 2013:
    @Diapolo indeed. I got this branch to build the Qt client on Mac OS 10.8. I’m still having some problems with std::basic_ostream and QtCore/qglobal.h when I use -mmacosx-version-min=10.5. Using -mmacosx-version-min=10.7 seems to make the first problem go away. The second problem is just a warning.

    CodeShark commented at 6:50 pm on January 10, 2013:
    -mmacosx-version-min=10.6 even works. But 10.5, no way.
  62. Added -lboost_regex to bitcoin-qt.pro. aa93b315d4
  63. Made wallet pointers in CWalletMap boost::shared_ptr<CWallet>. e0f3cbe20a
  64. Removed pwalletMain. Using pWalletMap->GetDefaultWallet() instead. eba5579499
  65. Renamed CWalletMap CWalletManager and pWalletMap pWalletManager. 6f3e40b96f
  66. Added Timer 3944f1d061
  67. Integrated timer with wallet. 64a9b45640
  68. CodeShark commented at 6:53 am on January 14, 2013: contributor
    Hmm, still having some issues with the default wallet not unloading at shutdown. Will need to go over the shutdown sequence to make sure all threads relinquish their pointers to it.
  69. Added wallet unloading tracers. Let rpcmining methods use nondefault wallet. a240960a0d
  70. Changed the way unlock time displays in listwallets. 41f561cad6
  71. Made wallet unlock timestamp UTC. 5bb560f24b
  72. gavinandresen commented at 4:08 pm on January 14, 2013: contributor

    Just to set expectations:

    This big a change, in this critical a part of the codebase, will need:

    • A comprehensive test plan, that exercises all the things that have changed.
    • Testing by at least two different people who aren’t developers, on Windows and either Linux or Mac

    See https://github.com/bitcoin/QA for the lastest QA process.

  73. Merged multiwallet(5bb560f) with master. 6c7f86ae37
  74. BitcoinPullTester commented at 5:56 am on January 24, 2013: none
    Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/1c45edce2fbe76f7e146ee12c1df80c66c5fa8f9 for binaries and test log.
  75. BitcoinPullTester commented at 9:58 pm on September 16, 2013: none

    Automatic sanity-testing: FAILED MERGE, see http://jenkins.bluematt.me/pull-tester/6c7f86ae371f955371fba05c7f747e4659cd39c8 for test log.

    This pull does not merge cleanly onto current master This test script verifies pulls every time they are updated. It, however, dies sometimes and fails to test properly. If you are waiting on a test, please check timestamps to verify that the test.log is moving at http://jenkins.bluematt.me/pull-tester/current/ Contact BlueMatt on freenode if something looks broken.

  76. MrLei commented at 5:02 pm on October 4, 2013: none
    How i can install bitcoind whit Dynamically Loadable Multiple Wallet ?
  77. gavinandresen commented at 1:10 am on October 21, 2013: contributor
    Rebase needed.
  78. Tranz5 commented at 4:02 am on November 13, 2013: none

    This is awesome work. I hope it makes it way to BTC soon. I’ve been playing with it for a bit now. Here are the issues I am working through.

    1. Export doesn’t work. ( Tried making BitCoinGui exportAction public and referencing it in WalletView::gotoHistoryPage but that only gives me default wallet) Still working on different methods to fix this.
    2. The RPC commands loadwallet and unloadwallet do not reflect in gui. I think the gui needs a connect to rpc commands.
    3. When clicking on the transaction on the right side of the gui, the transaction button doesn’t get focus.
    4. The gui can’t create a new wallet. using loadwallet then unloadwallet rcp, then load button in gui works, but..

    So far these are the only issues I have found.

    Thanks again for the hard work. I’ll share what I can when as I work through these changes. I am still new and trying to catchup as quick as possible. Any hints are appreciated it.

    Happy Bitcoining!

  79. Tranz5 commented at 5:33 am on December 1, 2013: none

    I also found that sign message didn’t work with other wallets.

    I have found a solution to all of these.

    I can do a pull request to this version, if this actually has a chance to be part of btc. I don’t have time to rebase though.

    Thanks!

  80. bananas2 commented at 2:39 am on March 24, 2014: none
    Is it already implemented?
  81. laanwj commented at 7:12 am on March 24, 2014: member
    No, the pull request was not kept up to date. I needs a lot of rebasing to apply to 0.9.x, which Gavin already noted 5 months ago.
  82. laanwj commented at 12:16 pm on April 3, 2014: member

    I’m going to close this. It has diverged too much from the current code base and no one seems to be interested in rebasing it.

    In case anyone ever wants to have a shot at implementing multi-wallet I’ll refer to to these code changes, as in principle they are good but they just arrived at the wrong time and were not kept in sync long enough to be tested properly and merged.

  83. laanwj closed this on Apr 3, 2014

  84. 6coind commented at 10:09 pm on December 19, 2015: none
    Noone can re-base this ? Amazing that this did not become the standard
  85. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-06-29 07:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me