Add WalletLocation class #14350

pull promag wants to merge 2 commits into bitcoin:master from promag:2018-09-walletinfo changing 13 files +85 −58
  1. promag commented at 3:59 pm on September 28, 2018: member

    Advantages of this change:

    • avoid resolving wallet absolute path and name repetitively and in multiple places;
    • avoid calling GetWalletDir in multiple places;
    • extract these details from the actual wallet implementation.

    The WalletLocation class can be a way to represent a wallet not yet loaded that exists in the wallet directory.

  2. MarcoFalke commented at 4:05 pm on September 28, 2018: member

    You accidentally removed a circular dependency:

    0Good job! The circular dependency "wallet/rpcwallet -> wallet/wallet -> wallet/rpcwallet" is no longer present.
    
  3. practicalswift commented at 4:33 pm on September 28, 2018: contributor

    Concept ACK

    Nice bonus with the removed circular dependency!

  4. DrahtBot commented at 5:32 pm on September 28, 2018: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #14552 (wallet: detecting duplicate wallet by comparing the db filename. by ken2812221)
    • #14437 (Refactor: Start to separate wallet from node by ryanofsky)
    • #13756 (wallet: “avoid_reuse” wallet flag for improved privacy by kallewoof)
    • #10973 (Refactor: separate wallet from node by ryanofsky)
    • #10102 ([experimental] Multiprocess bitcoin by ryanofsky)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  5. promag force-pushed on Sep 28, 2018
  6. promag force-pushed on Sep 28, 2018
  7. promag force-pushed on Sep 28, 2018
  8. promag force-pushed on Sep 28, 2018
  9. promag force-pushed on Sep 28, 2018
  10. fanquake added the label Wallet on Sep 28, 2018
  11. in src/wallet/walletutil.h:32 in 53aeb8553d outdated
    27+        , m_external(other.m_external)
    28+        , m_name(other.m_name)
    29+        , m_path(other.m_path) {}
    30+
    31+    //! Returns the wallet filename.
    32+    std::string GetFilename() const { return m_filename; };
    


    practicalswift commented at 6:55 am on September 29, 2018:
    Remove trailing semi-colon :-)
  12. in src/wallet/wallet.cpp:3832 in 53aeb8553d outdated
    3828@@ -3830,23 +3829,23 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string&
    3829     // 3. Path to a symlink to a directory.
    3830     // 4. For backwards compatibility, the name of a data file in -walletdir.
    3831     LOCK(cs_wallets);
    3832-    fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir());
    3833+    fs::path wallet_path = info.GetPath();
    


    practicalswift commented at 6:59 am on September 29, 2018:
    Make this const ref? :-)
  13. in src/wallet/walletutil.h:46 in 53aeb8553d outdated
    39+
    40+    //! Get wallet absolute path.
    41+    const fs::path& GetPath() const { return m_path; }
    42+
    43+    //! Return whether the wallet lives in the wallet directory. See ::GetWalletDir().
    44+    bool IsExternal() const { return m_external; }
    


    practicalswift commented at 7:01 am on September 29, 2018:
    IsExternal() and m_external seem unused?

    promag commented at 9:35 am on September 29, 2018:
    Now it’s used, I was going to push it in another PR.
  14. promag force-pushed on Sep 29, 2018
  15. promag force-pushed on Sep 29, 2018
  16. promag force-pushed on Oct 9, 2018
  17. promag commented at 9:51 pm on October 9, 2018: member
    I’ve rebase this with #14291 to avoid conflicts. Please review that one first.
  18. in src/wallet/wallet.h:671 in db58ab9608 outdated
    670@@ -671,7 +671,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
    671      * Used in debug logs and to send RPCs to the right wallet instance when
    


    promag commented at 9:56 pm on October 9, 2018:
    Self review, I have to update this comment and move to WalletInfo.
  19. promag force-pushed on Oct 15, 2018
  20. jonasschnelli added this to the "Blockers" column in a project

  21. ryanofsky commented at 9:09 pm on October 18, 2018: member

    This PR is doing two different things:

    1. Adding a WalletInfo class to hold information about a wallet’s location.
    2. Introducing a filesystem heuristic to determine whether or not a wallet is “external” and exposing this property over RPC.

    I like the first thing, but don’t think I like or understand the second thing and would prefer to see all of the m_external/IsExternal/"external" stuff moved out of this PR into a separate PR if it is going to be pursued.

    I also think WalletInfo should be have a more meaningful name. Maybe WalletLocation?

  22. promag commented at 9:28 pm on October 18, 2018: member

    Thanks @ryanofsky:

    1. WalletInfo comes from QFileInfo, but I agree the name is not clear. WalletLocation is too specific to paths?
    2. Sure I can move to other PR, but the idea is to separate internal wallets and external wallets in the UI.

    filesystem heuristic

    IIUC wallets inside -walletdir are internal, the others are external?

  23. ryanofsky commented at 9:45 pm on October 18, 2018: member

    I hope you will move the external stuff to a separate PR with a justification about why it is useful, so reviewers don’t need to guess and speculate about what it’s for (I don’t have an idea), and so we can talk about it separately from this refactoring stuff.

    Also, could you be clearer about what the problem is with WalletLocation? For example, does it imply something about the class which isn’t true? I don’t know what “too specific to paths” means.

  24. promag commented at 10:04 pm on October 18, 2018: member

    For example, does it imply something about the class which isn’t true?

    If GetName(), GetDisplayName() and eventually other attributes like IsExternal fit WalletLocation then I’m fine with that.

  25. promag force-pushed on Oct 18, 2018
  26. promag renamed this:
    Add WalletInfo class
    Add WalletLocation class
    on Oct 18, 2018
  27. meshcollider added the label Refactoring on Oct 18, 2018
  28. promag commented at 11:15 pm on October 18, 2018: member

    Took both suggestions from @ryanofsky and rebased.

    This is a dependency for full multi wallet support in the UI — there was a lot of duplicate code in #13100.

  29. in src/wallet/walletutil.cpp:96 in 31ba701c28 outdated
    91+    m_name = name.string();
    92+}
    93+
    94+std::string WalletLocation::GetDisplayName() const
    95+{
    96+    return m_name.empty() ? "[default wallet]" : m_name;
    


    meshcollider commented at 11:36 pm on October 18, 2018:
    This no longer puts brackets around the filename if it isn’t the default wallet?
  30. in src/qt/test/wallettests.cpp:136 in 37161b54a7 outdated
    132@@ -133,7 +133,7 @@ void TestGUI()
    133     for (int i = 0; i < 5; ++i) {
    134         test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
    135     }
    136-    std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>("mock", WalletDatabase::CreateMock());
    137+    std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(WalletLocation("mock"), WalletDatabase::CreateMock());
    


    meshcollider commented at 11:39 pm on October 18, 2018:
    Why does this mock wallet have a name, where all the other replacements you made don’t?
  31. promag force-pushed on Oct 19, 2018
  32. in src/wallet/walletutil.cpp:83 in 986982393f outdated
    74@@ -75,3 +75,29 @@ std::vector<fs::path> ListWalletDir()
    75 
    76     return paths;
    77 }
    78+
    79+WalletLocation::WalletLocation(const std::string& filename) : m_filename(filename)
    80+{
    81+    const fs::path wallet_dir = GetWalletDir();
    82+    m_path = fs::absolute(filename, wallet_dir);
    83+    fs::path name, parent = m_path;
    


    ryanofsky commented at 9:16 pm on October 19, 2018:

    This code added here is more complicated than it needs to be and it is not a refactoring because it would change behavior, and in bad ways for windows and case insensitive filesystems. If the intention is to change behavior, this should be done in separate, smaller PR and accompanied by tests so it can be better understood and discussed. For a clean refactoring in this PR, this entire function should just be:

    0WalletLocation::WalletLocation(const std::string& name) : m_name(name), m_path(fs::absolute(name, GetWalletDir()) {}
    

    And the m_filename and GetFileName() members should be dropped and all GetFileName() calls changed to GetName().

    From: https://github.com/bitcoin/bitcoin/blob/d387507aeca652a5569825af65243536f2ce26ea/src/bitcoin-cli.cpp#L55

    The way -rpcwallet and -wallet arguments were designed to work is that there is no string or path manipulation done when matching wallet names that would ever cause the wrong wallet to be used or the right wallet not to be found.

    So for example, if a user starts bitcoind with -wallet=c:\wallets\bob\2018\ they should be able to run bitcoin-cli with the exact same -rpcwallet=c:\wallets\bob\2018\ value, and not have to figure out a different value like bob/2018 or C:\Wallets\Bob\2018 or whatever else the code added in this function might change it to.

    I think we could consider changing this behavior, but only if we do it in a clear and deliberate way. I’d definitely want it to be done after this refactoring instead of simultaneously with it.

  33. in src/wallet/walletutil.h:28 in 986982393f outdated
    23+    fs::path m_path;
    24+
    25+public:
    26+    explicit WalletLocation() {}
    27+    explicit WalletLocation(const std::string& filename);
    28+    explicit WalletLocation(const WalletLocation& other)
    


    ryanofsky commented at 9:20 pm on October 19, 2018:
    I think you could drop this and just rely on the default copy constructor.
  34. in src/wallet/walletutil.h:29 in 986982393f outdated
    35+
    36+    //! Returns the wallet display name.
    37+    std::string GetDisplayName() const;
    38+
    39+    //! Get wallet name.
    40+    const std::string& GetName() const { return m_name; }
    


    ryanofsky commented at 9:28 pm on October 19, 2018:
    Having both GetName and GetFileName in this class is unnecessarily confusing, and how these functions are called breaks current behavior. I can see why it’d be useful to use canonicalized wallet names in the gui in the future, but I think that functionality should be added separately when it’s actually ready to be used.
  35. promag commented at 9:40 pm on October 19, 2018: member
    @ryanofsky ok. The problem I had was when I opened an external wallet (with the file dialog) that was in the wallet dir. Whatever the user chooses it should be resolved. I can leave this problem for a later PR though.
  36. ryanofsky commented at 5:55 pm on October 22, 2018: member

    The problem I had was when I opened an external wallet (with the file dialog) that was in the wallet dir. Whatever the user chooses it should be resolved.

    I think loading a wallet from the gui can basically work the same as calling the loadwallet RPC except if a user browsed for a wallet path, and the path is literally underneath <walletdir>, then the <walletdir> prefix should get stripped from the wallet name. Also, loading the same wallet twice should not be an error. The GUI can handle the “duplicates fileid” condition https://github.com/bitcoin/bitcoin/blob/5c25409d6851182c5e351720cee36812c229b77a/src/wallet/db.cpp#L48 by switching to the already open wallet and maybe showing a notification instead of an error.

    Both these things could be be implemented in the GUI with minimal changes to wallet code.

  37. promag force-pushed on Oct 23, 2018
  38. promag force-pushed on Oct 24, 2018
  39. DrahtBot added the label Needs rebase on Oct 24, 2018
  40. promag force-pushed on Oct 25, 2018
  41. wallet: Add WalletLocation utility class 01a4c095c8
  42. promag force-pushed on Oct 25, 2018
  43. DrahtBot removed the label Needs rebase on Oct 25, 2018
  44. wallet: Refactor to use WalletLocation 65f3672f3b
  45. promag force-pushed on Oct 25, 2018
  46. in src/wallet/rpcwallet.cpp:2414 in 65f3672f3b
    2414-    if (fs::symlink_status(wallet_path).type() == fs::file_not_found) {
    2415-        throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Wallet " + wallet_file + " not found.");
    2416-    } else if (fs::is_directory(wallet_path)) {
    2417+    if (!location.Exists()) {
    2418+        throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Wallet " + location.GetName() + " not found.");
    2419+    } else if (fs::is_directory(location.GetPath())) {
    


    ryanofsky commented at 3:42 pm on October 25, 2018:
    Possible future improvement: It might be nice to add a WalletLocation method to hold directory checking logic below. Maybe WalletLocation::HasData, or WalletLocation::IsEmpty, or something like that. After #14552 (aef19be5851ceb3b324fd80756060a00aad8e61c) this could also use SplitWalletPath.

    promag commented at 9:48 pm on October 26, 2018:
    Is it bad to add WalletLocation::GetEnvironmentPath() and WalletLocation::GetDatabasePath()?

    ryanofsky commented at 6:35 pm on October 30, 2018:

    Is it bad to add WalletLocation::GetEnvironmentPath() and WalletLocation::GetDatabasePath()?

    It’s not terrible, but I think it’d be better not to have berkeley stuff baked into the WalletLocation interface. Maybe a wallet location doesn’t need to be a btree file and environment directory. Maybe it could be some other type of database path or connection string.

    I think it would be an improvement if this code were more like:

    0if (!location.Exists()) {
    1  throw RPCError("Specified wallet path doesn't exist. Call createwallet to create a wallet at this path.");
    2} else if (!location.HasData()) {
    3  throw RPCError("Not loading wallet. Specified path doesn't does not appear to be a valid wallet.");
    4}
    

    But I think more ideally BerkeleyDatabase would have a bool create option that that loadwallet would set false and createwallet would set true, so error checking at this level could be removed entirely, and shared with the wallet tool from #13926, for example.

  47. ryanofsky approved
  48. ryanofsky commented at 3:47 pm on October 25, 2018: member
    utACK 65f3672f3b82a6fa30e5171f85bc8d8a29e0797e
  49. ken2812221 commented at 9:15 am on October 30, 2018: contributor
    utACK 65f3672f3b82a6fa30e5171f85bc8d8a29e0797e
  50. ryanofsky approved
  51. laanwj commented at 4:01 pm on November 1, 2018: member

    utACK 65f3672f3b82a6fa30e5171f85bc8d8a29e0797e

    It’s not terrible, but I think it’d be better not to have berkeley stuff baked into the WalletLocation interface.

    I tend to agree, it’s best to keep it more or less database independent. No matter the rest of the change it should at least not become more difficult to swap for another database.

  52. meshcollider commented at 6:49 pm on November 4, 2018: contributor
  53. laanwj merged this on Nov 5, 2018
  54. laanwj closed this on Nov 5, 2018

  55. laanwj referenced this in commit 46eb2755d4 on Nov 5, 2018
  56. promag deleted the branch on Nov 5, 2018
  57. fanquake removed this from the "Blockers" column in a project

  58. promag referenced this in commit b35a71827b on Mar 11, 2019
  59. promag referenced this in commit 7e04e0954c on Mar 11, 2019
  60. promag referenced this in commit 21693ff0b7 on Mar 11, 2019
  61. promag referenced this in commit 16e5759455 on Mar 11, 2019
  62. laanwj referenced this in commit 6cf81b01b4 on Mar 20, 2019
  63. sidhujag referenced this in commit 74f7fa48d7 on Mar 28, 2019
  64. sidhujag referenced this in commit 5417a389e5 on Mar 28, 2019
  65. sidhujag referenced this in commit 3ee64a0aa7 on Mar 28, 2019
  66. uhliksk referenced this in commit e09992d662 on Apr 21, 2019
  67. uhliksk referenced this in commit be95fb862d on Apr 21, 2019
  68. Rishabh42 referenced this in commit ce3547fae6 on Apr 22, 2019
  69. uhliksk referenced this in commit f7e5f6ffaa on May 1, 2019
  70. uhliksk referenced this in commit 3167021c6b on May 1, 2019
  71. jasonbcox referenced this in commit c6620b59cb on Dec 20, 2019
  72. xdustinface referenced this in commit 13bca14747 on Apr 4, 2021
  73. xdustinface referenced this in commit d2a3fd63fa on Apr 4, 2021
  74. xdustinface referenced this in commit 0901ae5227 on Apr 4, 2021
  75. xdustinface referenced this in commit 8bb98a5337 on Apr 4, 2021
  76. xdustinface referenced this in commit d4ac6d62a9 on Apr 5, 2021
  77. xdustinface referenced this in commit 26b0a4dfc8 on Apr 13, 2021
  78. Munkybooty referenced this in commit 93ef7d55a7 on Jul 22, 2021
  79. Munkybooty referenced this in commit a2c6db9caa on Jul 22, 2021
  80. MarcoFalke 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-12-18 15:12 UTC

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