Use std::filesystem. Remove Boost Filesystem & System #20744

pull fanquake wants to merge 4 commits into bitcoin:master from fanquake:use_std_filesystem changing 50 files +252 −563
  1. fanquake commented at 2:27 pm on December 22, 2020: member

    This PR replaces our Boost Filesystem usage with std::filesystem and includes dropping Boost System as a dependency. It includes a squashed down version of the changes from #19245.

    A macro has been added, modelling how we check for -latomic to facilitate linking with -lstdc++fs when required. This is ~GCC < 9.1 & ~Clang < 9.0, however not always. i.e you could be using Clang 7 on top of a GCC 9 installation (i.e Ubuntu Focal) and use <filesystem> without passing any additional arguments. I’ve tested this with GCC 8 on Bionic, Clang 7 on Focal & with Apple Clang 12.0.0 on macOS.

    Guix build:

     0bash-5.1# find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum
     1c1f9b326f9be4140f00cebeae5ff8de428a2fb8ecced539fcc36c53f53bfecf4  guix-build-07269321f38e/output/aarch64-linux-gnu/SHA256SUMS.part
     2b44aca3bcf5ea92a3a6c48c24d6f85576f425f59b73528d4d00c20e950cf2128  guix-build-07269321f38e/output/aarch64-linux-gnu/bitcoin-07269321f38e-aarch64-linux-gnu-debug.tar.gz
     327a5553f7bd14797293fc40c5fb131c91e98a61d5481a283f13a1d0497eb5ed8  guix-build-07269321f38e/output/aarch64-linux-gnu/bitcoin-07269321f38e-aarch64-linux-gnu.tar.gz
     499e55a88823f6095864a09c9eaa824e24d9ec527380eb394f751c7205b930f69  guix-build-07269321f38e/output/arm-linux-gnueabihf/SHA256SUMS.part
     5b720b2724fa47fde584f58ed3b587f1d1183523540777fd367ab7e582605cfea  guix-build-07269321f38e/output/arm-linux-gnueabihf/bitcoin-07269321f38e-arm-linux-gnueabihf-debug.tar.gz
     6c19c247f4e9e0d7f888ac8ba9de1c12d382f48fa828a685d4fe02818a18abd1f  guix-build-07269321f38e/output/arm-linux-gnueabihf/bitcoin-07269321f38e-arm-linux-gnueabihf.tar.gz
     755b49ccb38de03bb95101354a16fd8d2190abede5ccc0d9b00b40c0cd526a2f6  guix-build-07269321f38e/output/arm64-apple-darwin/SHA256SUMS.part
     8baa44752470a6be9acae1c2f8fd1b9bc37afb00971787ea11fbaeddc9ab7c4aa  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-arm64-apple-darwin.tar.gz
     9ad7df4d8026d5bcce1321cdccc2e1820e8a8bb7e1064ed16e20a7ea354057fd2  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.dmg
    10f342066dc34a14d67c47779a2413a14633a996e8e7ddca89ae0184e23ef99efd  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.tar.gz
    11f6905346a5d48f57805fb062d0247ab5007c89047070a0b3125941dd1a2b8aa6  guix-build-07269321f38e/output/dist-archive/bitcoin-07269321f38e.tar.gz
    12a1f6c4b2b118dbd89770801f0bcffd2218b82df408cd227e34c40493469bb7a2  guix-build-07269321f38e/output/powerpc64-linux-gnu/SHA256SUMS.part
    13ba8359426e523bf013d93579c1bedc57380214c8170a9743b64ec1a8a3bbccbf  guix-build-07269321f38e/output/powerpc64-linux-gnu/bitcoin-07269321f38e-powerpc64-linux-gnu-debug.tar.gz
    14b0bb500c274a683ea28ecbc1e8f18c618a9f8acb00045f80ae43c515288402c0  guix-build-07269321f38e/output/powerpc64-linux-gnu/bitcoin-07269321f38e-powerpc64-linux-gnu.tar.gz
    1538c85e9589e092cd3aa08996aa383c0ccd5c73208943389741355a6eb7f72537  guix-build-07269321f38e/output/powerpc64le-linux-gnu/SHA256SUMS.part
    1650fcba7942ff48d91e84c093fda0affc17e46167fe1d5137c6e14c5c41f289d1  guix-build-07269321f38e/output/powerpc64le-linux-gnu/bitcoin-07269321f38e-powerpc64le-linux-gnu-debug.tar.gz
    17fa08ef1ceca072e014faa95ffee945954b2976fa28f90926b87ab0e5f15f8ca5  guix-build-07269321f38e/output/powerpc64le-linux-gnu/bitcoin-07269321f38e-powerpc64le-linux-gnu.tar.gz
    18e52dd80a9c306d6aeb544acaa1f4ed560b6b92b5184764a05026d45451aa2e94  guix-build-07269321f38e/output/riscv64-linux-gnu/SHA256SUMS.part
    19864e0a16c485b4159cec3ee0a83b046f1b1c3bc821670011c5ac5cd09ddfb91f  guix-build-07269321f38e/output/riscv64-linux-gnu/bitcoin-07269321f38e-riscv64-linux-gnu-debug.tar.gz
    204a061172181322e7ad0cf06405bf74f4c8683eaba3a67ecfd46158cba7627f62  guix-build-07269321f38e/output/riscv64-linux-gnu/bitcoin-07269321f38e-riscv64-linux-gnu.tar.gz
    21876d82251853205420dffe7237523fc6ee3d09f78bf74cc03dc71f548446f335  guix-build-07269321f38e/output/x86_64-apple-darwin/SHA256SUMS.part
    223f82b2e62c60eee68e7b8fc28e4792e069e3c2cd780ee2d67290ca422cdbc47c  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.dmg
    234ccdd4c410cac9d627e54ce83ee4816608681735da3cb93c60c5eb70ca86337a  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.tar.gz
    242179d36b2f60e28c15262d4e51f27465b5ae077f60e550345e125683ca611066  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx64.tar.gz
    25b377e72fe84b6a982b8d414d60c85e6319523dff50dc852a0ba907f6d850ddd0  guix-build-07269321f38e/output/x86_64-linux-gnu/SHA256SUMS.part
    268547e2f582ce05ae6a6224793b64efb2eb63f2816bf0bed5d53fcc4786274597  guix-build-07269321f38e/output/x86_64-linux-gnu/bitcoin-07269321f38e-x86_64-linux-gnu-debug.tar.gz
    2783b64805aa39f31a6fa4c2ed41e029c3be084e6dea06b90fac1ebca5c95bce29  guix-build-07269321f38e/output/x86_64-linux-gnu/bitcoin-07269321f38e-x86_64-linux-gnu.tar.gz
    
  2. fanquake added the label Refactoring on Dec 22, 2020
  3. fanquake added the label Build system on Dec 22, 2020
  4. MarcoFalke closed this on Dec 22, 2020

  5. MarcoFalke reopened this on Dec 22, 2020

  6. MarcoFalke added the label Waiting for other on Dec 22, 2020
  7. in configure.ac:79 in 2733fe31ba outdated
    75@@ -76,6 +76,9 @@ AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
    76 dnl Check if -latomic is required for <std::atomic>
    77 CHECK_ATOMIC
    78 
    79+dnl check if -lstdc++fs is required for <std::filesystem>
    


    vasild commented at 2:47 pm on December 22, 2020:
    nit: remove <> around std::filesystem - it is not a header.
  8. in doc/dependencies.md:10 in 2733fe31ba outdated
     6@@ -7,11 +7,11 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
     7 | --- | --- | --- | --- | --- | --- |
     8 | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No |  |  |
     9 | Boost | [1.71.0](https://www.boost.org/users/download/) | [1.58.0](https://github.com/bitcoin/bitcoin/pull/19667) | No |  |  |
    10-| Clang |  | [5.0+](https://releases.llvm.org/download.html) (C++17 support) |  |  |  |
    11+| Clang |  | [7.0+](https://releases.llvm.org/download.html) (C++17 & std::filesystem support) |  |  |  |
    


    vasild commented at 2:49 pm on December 22, 2020:
    nit: std::filesystem is part of C++17, maybe not worth mentioning explicitly.

    ryanofsky commented at 5:07 pm on February 5, 2021:

    In commit “build: remove boost::filesystem” (9f37a39b11b240f75b97fb565e6d8cf44972ec49)

    This change seems like it belongs in previous commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7) instead of this one.

  9. fanquake force-pushed on Dec 22, 2020
  10. MarcoFalke removed the label Waiting for other on Dec 22, 2020
  11. in ci/test/00_setup_env_native_nowallet.sh:10 in ac8a44674b outdated
     6@@ -7,8 +7,8 @@
     7 export LC_ALL=C.UTF-8
     8 
     9 export CONTAINER_NAME=ci_native_nowallet
    10-export DOCKER_NAME_TAG=ubuntu:18.04  # Use bionic to have one config run the tests in python3.6, see doc/dependencies.md
    11-export PACKAGES="python3-zmq clang-5.0 llvm-5.0"  # Use clang-5 to test C++17 compatibility, see doc/dependencies.md
    12+export DOCKER_NAME_TAG=ubuntu:20.04
    


    MarcoFalke commented at 2:54 pm on December 22, 2020:

    Would be nice to not change this. clang-7 is also in bionic:


    MarcoFalke commented at 12:36 pm on February 9, 2021:
    Still not addressed?

    fanquake commented at 12:38 pm on February 9, 2021:
    That’s why it hasn’t been marked as resolved.

    fanquake commented at 12:53 pm on February 9, 2021:
    This has now been dropped.
  12. in ci/test/00_setup_env_win64.sh:10 in ac8a44674b outdated
     6@@ -7,7 +7,7 @@
     7 export LC_ALL=C.UTF-8
     8 
     9 export CONTAINER_NAME=ci_win64
    10-export DOCKER_NAME_TAG=ubuntu:18.04  # Check that bionic can cross-compile to win64 (bionic is used in the gitian build as well)
    11+export DOCKER_NAME_TAG=ubuntu:20.04
    


    MarcoFalke commented at 2:55 pm on December 22, 2020:
    the comment should stay to say that this is the version used in gitian as well. I presume this pull is blocked (waiting on) gitian getting bumped to focal? Thus the label “waiting for other”.

    MarcoFalke commented at 2:58 pm on December 22, 2020:
    Oh, and this has to be bumped in the cirrus yaml as well (Sorry, confusing, but I didn’t find a way around this redundancy)

    fanquake commented at 3:07 pm on December 22, 2020:

    Oh, and this has to be bumped in the cirrus yaml as well

    Thanks. Did not realise that was required.


    fanquake commented at 12:33 pm on February 9, 2021:
    Gitian has now been bumped.
  13. MarcoFalke commented at 2:56 pm on December 22, 2020: member
    Concept ACK for 0.23 (earliest), given that this again requires a bunch of aggressive bumps.
  14. in src/rpc/blockchain.cpp:2399 in ac8a44674b outdated
    2392@@ -2393,10 +2393,10 @@ static RPCHelpMan dumptxoutset()
    2393         },
    2394         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
    2395 {
    2396-    fs::path path = fs::absolute(request.params[0].get_str(), GetDataDir());
    2397+    fs::path path = fs::absolute(GetDataDir() / request.params[0].get_str());
    2398     // Write to a temporary path and then move into `path` on completion
    2399     // to avoid confusion due to an interruption.
    2400-    fs::path temppath = fs::absolute(request.params[0].get_str() + ".incomplete", GetDataDir());
    2401+    fs::path temppath = fs::absolute(GetDataDir() / request.params[0].get_str() / ".incomplete");
    


    vasild commented at 2:59 pm on December 22, 2020:
    Shouldn’t that be + instead of / before ".incomplete"?

    fanquake commented at 6:30 am on December 24, 2020:
    Thanks, I’ve fixed this in the next push.
  15. MarcoFalke deleted a comment on Dec 22, 2020
  16. in src/test/util_tests.cpp:55 in ac8a44674b outdated
    49@@ -50,19 +50,19 @@ BOOST_AUTO_TEST_CASE(util_datadir)
    50     ClearDatadirCache();
    51     const fs::path dd_norm = GetDataDir();
    52 
    53-    gArgs.ForceSetArg("-datadir", dd_norm.string() + "/");
    54+    gArgs.ForceSetArg("-datadir", dd_norm.string());
    


    vasild commented at 3:01 pm on December 22, 2020:
    Why this change? Does it break with + "/"?

    ryanofsky commented at 4:36 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    Would be more reassuring that behavior was not changing if tests could stay the same. Would be useful to know the reason for changes to this test if they are can’t be reverted.


    fanquake commented at 12:44 pm on February 9, 2021:

    Why this change? Does it break with + “/”?

    Yes, at ef8c98b1a54280f279f5319f386c44026893bf1f this currently fails with the trailing slash:

    0error: in "util_tests/util_datadir": check dd_norm == GetDataDir() has failed ["/var/folders/z2/cn877pxd3czdfh47mfkmbwgm0000gn/T/test_common_Bitcoin Core/873b1e644e770a9d5cdfc8f89323a344256001e7cedc14e18f2ae7c4a8ea8f94" != "/var/folders/z2/cn877pxd3czdfh47mfkmbwgm0000gn/T/test_common_Bitcoin Core/873b1e644e770a9d5cdfc8f89323a344256001e7cedc14e18f2ae7c4a8ea8f94/"]
    

    ryanofsky commented at 11:41 pm on February 11, 2021:

    re: #20744 (review)

    Yes, at ef8c98b this currently fails with the trailing slash:

    Thanks, I think this can be marked resolved, but I it would be good to add a warning in the commit description to alert reviewers and people trying to track down regressions in the future (in case there are bugs), like: “Warning: Replacing fs::system_complete calls with fs::absolute calls in this commit may cause minor changes in behavior because fs::absolute no longer strips trailing slashes, but these changes are believed to be safe.”

    If we really wanted to be paranoid here, we could add a wrapper function emulating the old behavior, but I think the new behavior actually makes more sense (avoids gratuitous changes to strings), and is not likely to cause any serious problems.


    fanquake commented at 1:49 am on February 17, 2021:
    I’ve added to the commit message, so will mark this as resolved.
  17. fanquake force-pushed on Dec 22, 2020
  18. in src/wallet/wallettool.cpp:108 in 8d148b93bb outdated
    104@@ -105,7 +105,7 @@ static void WalletShowInfo(CWallet* wallet_instance)
    105 
    106 bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command, const std::string& name)
    107 {
    108-    fs::path path = fs::absolute(name, GetWalletDir());
    109+    fs::path path = fs::absolute((name == "") ? GetWalletDir() : (GetWalletDir() / name));
    


    vasild commented at 3:13 pm on December 22, 2020:
    Why not just GetWalletDir() / name even if name is empty?

    ryanofsky commented at 8:06 pm on January 21, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (f449c26f30bb8e223d4d7833c579d555a0005daa)

    re: #20744 (review)

    Why not just GetWalletDir() / name even if name is empty?

    See #20744 (comment), this avoids adding an empty path component and trailing slash if name is empty. This code should be simpler when this is rebased after #20932

  19. DrahtBot commented at 8:43 pm on December 22, 2020: 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:

    • #23931 (create bitcoin.conf on first run with template by prayank23)
    • #22472 (fuzz: Add environment option to keep /tmp/ clean by agroce)
    • #22380 (build: add and use C_STANDARD and CXX_STANDARD in depends by fanquake)
    • #17127 (util: Correct permissions for datadir and wallets subdir by hebasto)

    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.

  20. in src/wallet/wallet.cpp:3783 in 8d148b93bb outdated
    3779@@ -3780,11 +3780,11 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
    3780     // 2. Path to an existing directory.
    3781     // 3. Path to a symlink to a directory.
    3782     // 4. For backwards compatibility, the name of a data file in -walletdir.
    3783-    const fs::path& wallet_path = fs::absolute(name, GetWalletDir());
    3784+    const fs::path& wallet_path = fs::absolute((name == "") ? GetWalletDir() : (GetWalletDir() / name));
    


    mjdietzx commented at 3:33 pm on December 23, 2020:
    same: “Why not just GetWalletDir() / name even if name is empty?”

    ryanofsky commented at 8:03 pm on January 21, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (f449c26f30bb8e223d4d7833c579d555a0005daa)

    re: #20744 (review)

    same: “Why not just GetWalletDir() / name even if name is empty?”

    See #20744 (comment), this avoids adding an empty path component and trailing slash if name is empty. This code should be simpler when this is rebased after #20932

  21. in src/util/system.cpp:793 in 8d148b93bb outdated
    742-    if (fNetSpecific)
    743-        path /= BaseParams().DataDir();
    744+    if (fNetSpecific) {
    745+        if (!BaseParams().DataDir().empty()) {
    746+            path /= BaseParams().DataDir();
    747+        }
    


    mjdietzx commented at 3:40 pm on December 23, 2020:
    similar to “Why not just GetWalletDir() / name even if name is empty?”, is another if branch really needed here?

    ryanofsky commented at 8:05 pm on January 21, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (f449c26f30bb8e223d4d7833c579d555a0005daa)

    re: #20744 (review)

    similar to “Why not just GetWalletDir() / name even if name is empty?”, is another if branch really needed here?

    See #20744 (comment), this avoids adding an empty path component and trailing slash if the base datadir is empty


    kiminuo commented at 10:01 am on January 22, 2021:

    @fanquake I believe this one should be:

    0path = fsbridge::AbsPathJoin(path, BaseParams().DataDir());
    
  22. mjdietzx commented at 4:00 pm on December 23, 2020: contributor

    Nice‼️ Concept Ack

    I didn’t have any problems building and running some tests locally on my machine. Also, there’s a minor TODO that kind of got lost in the mix here. I had a PR for it when we were on boost #20265

    I rebased on your branch and tested it out, seems to work: https://github.com/mjdietzx/bitcoin/commit/55bafb983d9642e304beefd21017aa4099e96ec3 - not sure if you want to pull it into this PR, or once this get merged I’ll re-open the PR

  23. in src/wallet/load.cpp:65 in 8d148b93bb outdated
    61@@ -62,7 +62,7 @@ bool VerifyWallets(interfaces::Chain& chain)
    62     std::set<fs::path> wallet_paths;
    63 
    64     for (const auto& wallet_file : gArgs.GetArgs("-wallet")) {
    65-        const fs::path path = fs::absolute(wallet_file, GetWalletDir());
    66+        const fs::path path = fs::absolute(GetWalletDir() / wallet_file);
    


    ryanofsky commented at 5:21 pm on December 23, 2020:
    I think this isn’t equivalent if wallet_file is the empty string (this will add trailing slash now, wouldn’t add trailing slash previously).

    kiminuo commented at 2:21 pm on January 13, 2021:

    Yes, this simple sample confirms it:

     0// Run with: g++ --std=c++17 path.cpp && ./a.out
     1
     2#include <string>
     3#include <iostream>
     4#include <filesystem>
     5namespace fs = std::filesystem;
     6
     7int main()
     8{
     9    fs::path walletDir = "/home/user";
    10    std::string wallet_file = "";
    11    fs::path path = fs::absolute(walletDir / wallet_file);
    12
    13    std::cout << "walletDir = " << walletDir << "\n"; // walletDir = "/home/user"
    14    std::cout << "path      = " << path << "\n";      // path      = "/home/user/"
    15}
    

    ryanofsky commented at 8:01 pm on January 21, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (f449c26f30bb8e223d4d7833c579d555a0005daa)

    re: #20744 (review)

    Yes, this simple sample confirms it:

    Issue should be resolved when this is rebased after #20932.


    fanquake commented at 1:17 am on February 10, 2021:
    This has been rebased post #20932, so marking this as resolved.
  24. ryanofsky commented at 5:53 pm on December 23, 2020: member

    This seems good, but it would be nice to move code changes to their own PR separate from the build changes, so they can get better review and so the final code is simpler. (It would be nice if final code wasn’t checking for empty strings multiple places and wasn’t calling fs::absolute on paths already known to be absolute.)

    I think an initial PR simplifying this one would just replace fs::system_complete(x) with fs::absolute(x) and replace fs::absolute(x, y) with AbsPathJoin(y, x) everywhere. AbsPathJoin would be a util function defined like:

    0fs::path AbsPathJoin(fs::path p1, fs::path p2)
    1{
    2    assert(p1.is_absolute());
    3    return boost::filesystem::absolute(p2, p1);
    4}
    

    Then I think this PR wouldn’t need to touch any meaningful code except one line in AbsPathJoin:

    0fs::path AbsPathJoin(fs::path p1, fs::path p2)
    1{
    2    assert(p1.is_absolute());
    3    return p2.empty() ? p1 : p1 / p2;
    4}
    
  25. kiminuo commented at 6:21 pm on December 23, 2020: contributor
    @ryanofsky It is maybe worth reading “Differences between filesystem implementations that affects Bitcoin code” in #19245.
  26. ryanofsky commented at 6:59 pm on December 23, 2020: member

    @ryanofsky It is maybe worth reading “Differences between filesystem implementations that affects Bitcoin code” in #19245.

    Thanks, I saw it but don’t think it takes into account the “appends path::preferred_separator” behavior described https://en.cppreference.com/w/cpp/filesystem/path/append which can result in trailing slashes and is different from boost::absolute behavior https://www.boost.org/doc/libs/1_66_0/libs/filesystem/doc/reference.html#absolute.

    Also I think it is clearer and better to avoid calling fs::absolute on paths that we already know are absolute. Ideally we would go further and never call fs::absolute or fs::system_complete after daemonization. Behavior of code shouldn’t change depending on the process working directory, and in most cases it makes sense for usability to interpret paths relative to the data directory or wallet directory, not the process working directory.

  27. practicalswift commented at 11:05 pm on December 27, 2020: contributor
    Concept ACK
  28. DrahtBot added the label Needs rebase on Jan 7, 2021
  29. DrahtBot commented at 11:46 am on January 13, 2021: member

    🕵️ @laanwj @harding have been requested to review this pull request as specified in the REVIEWERS file.

  30. kiminuo referenced this in commit 72205add2a on Jan 15, 2021
  31. kiminuo referenced this in commit 8fbb7a8151 on Jan 15, 2021
  32. kiminuo referenced this in commit 215c784650 on Jan 15, 2021
  33. kiminuo referenced this in commit d867d7a64c on Jan 15, 2021
  34. kiminuo referenced this in commit da9caa1ced on Jan 15, 2021
  35. MarcoFalke referenced this in commit 45952dab9d on Jan 21, 2021
  36. ryanofsky commented at 8:22 pm on January 21, 2021: member
    Now that #20932 is merged, the messier path joining code and bugs here can disappear when this is rebased. The call sites where AbsPathJoin is used should no longer have to change. And the AbsPathJoin implementation can simply be changed to return path.empty() ? base : base / path instead of fs::absolute(path, base).
  37. kiminuo commented at 10:23 pm on January 21, 2021: contributor

    I have attempted to do the rebase with the fsbridge::AbsPathJoin modifications:

  38. fanquake force-pushed on Jan 22, 2021
  39. fanquake commented at 9:28 am on January 22, 2021: member
    Thanks @ryanofsky, @kiminuo & others who have commented. I’ve rebased to account for #20932 and made changes as suggested by Russ.
  40. fanquake force-pushed on Jan 22, 2021
  41. DrahtBot removed the label Needs rebase on Jan 22, 2021
  42. kiminuo commented at 3:05 pm on January 22, 2021: contributor

    I can see that [depends, sanitizers: thread (TSan), no gui] [focal] check (https://github.com/bitcoin/bitcoin/pull/20744/checks?check_run_id=1747977815) fails so I have run: MAKEJOBS="-j15" FILE_ENV="./ci/test/00_setup_env_native_tsan.sh" ./ci/test_run_all.sh to get:

     0test  2021-01-22T13:56:39.722000Z TestFramework.node0 (DEBUG): Node stopped 
     1 test  2021-01-22T13:56:39.723000Z TestFramework.node1 (DEBUG): Node stopped 
     2 test  2021-01-22T13:56:39.723000Z TestFramework (WARNING): Not cleaning up dir /home/bitcoin/bitcoin/ci/scratch/test_runner/test_runner__🏃_20210122_135553/wallet_hd_193 
     3 test  2021-01-22T13:56:39.723000Z TestFramework (ERROR): Test failed. Test logging available at /home/bitcoin/bitcoin/ci/scratch/test_runner/test_runner__🏃_20210122_135553/wallet_hd_193/test_framework.log 
     4 test  2021-01-22T13:56:39.746000Z TestFramework (ERROR): 
     5 test  2021-01-22T13:56:39.754000Z TestFramework (ERROR): Hint: Call /home/bitcoin/bitcoin/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/combine_logs.py '/home/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193' to consolidate all logs 
     6 test  2021-01-22T13:56:39.754000Z TestFramework (ERROR): 
     7 test  2021-01-22T13:56:39.754000Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log. 
     8 test  2021-01-22T13:56:39.754000Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues 
     9 test  2021-01-22T13:56:39.755000Z TestFramework (ERROR): 
    10
    11
    12TEST                                             | STATUS    | DURATION
    13
    14wallet_hd.py                                     |  Failed  | 45 s
    15
    16ALL                                              |  Failed  | 45 s (accumulated) 
    

    and then docker attach <ID> and combined logs per instructions:

     0node1 2021-01-22T13:56:25.176678Z [httpworker.2] error copying wallet.dat to /home/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193/node1/hd.bak - filesystem error: in equivalent: Operation not supported [/work/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193/node1/regtest/wallets/wallet.dat] [/work/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193/node1/hd.bak] 
     1 test  2021-01-22T13:56:38.577000Z TestFramework (ERROR): JSONRPC error 
     2                                   Traceback (most recent call last):
     3                                     File "/work/bitcoin/bitcoin/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 126, in main
     4                                       self.run_test()
     5                                     File "/work/bitcoin/bitcoin/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/wallet_hd.py", line 46, in run_test
     6                                       self.nodes[1].backupwallet(os.path.join(self.nodes[1].datadir, "hd.bak"))
     7                                     File "/work/bitcoin/bitcoin/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/coverage.py", line 47, in __call__
     8                                       return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
     9                                     File "/work/bitcoin/bitcoin/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/authproxy.py", line 146, in __call__
    10                                       raise JSONRPCException(response['error'], status)
    11                                   test_framework.authproxy.JSONRPCException: Error: Wallet backup failed! (-4)
    

    and now the files tested on equivalence:

    • File /work/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193/node1/regtest/wallets doe/wallet.dat` does exist.
    • File /work/bitcoin/bitcoin/ci/scratch/test_runner/test_runner_₿_🏃_20210122_135553/wallet_hd_193/node1/hd.bak does NOT exist.

    And now why do we get that filesystem error: in equivalent: Operation not supported?

    I have put together two samples for fs::equivalent:

     0// Run with: g++ --std=c++17 equivalent.cpp17.cpp && ./a.out
     1
     2#include <string>
     3#include <iostream>
     4#include <filesystem>
     5namespace fs = std::filesystem;
     6
     7int main()
     8{
     9    fs::path pathSrc = "/home/user/a.log";
    10    fs::path pathDest = "/home/user/b.log";
    11    bool success = fs::equivalent(pathSrc, pathDest);
    12
    13    std::cout << "Result is: " << (int)success << "\n";
    14
    15    // # Case "Both files do not exist"
    16    // 
    17    // Exception is thrown:
    18    // 
    19    // > terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
    20    // > what():  filesystem error: cannot check file equivalence: No such file or directory [/home/user/a.log] [/home/user/b.log]
    21    // > Aborted (core dumped)
    22
    23    // # Case "pathSrc exists, pathDest does not"
    24    //
    25    // No exception. Std output is:
    26    // > Result is: 0
    27
    28    // # Case "Both pathSrc and pathDest exist but are different."
    29    //
    30    // No exception. Std output is:
    31    // > Result is: 0    
    32
    33    // # Case "Both pathSrc and pathDest exist and b.log is symlink for a.log." (`ln -s a.log b.log`)
    34    //
    35    // No exception. Std output is:
    36    // > Result is: 0    
    37}
    

    and Boost variant:

     0// Run with: g++ equivalent.boost.cpp -lboost_system -lboost_filesystem && ./a.out
     1
     2#include <string>
     3#include <iostream>
     4#include <boost/filesystem.hpp>
     5#include <boost/filesystem/fstream.hpp>
     6namespace fs = boost::filesystem;
     7
     8int main()
     9{
    10    fs::path pathSrc = "/home/user/a.log";
    11    fs::path pathDest = "/home/user/b.log";
    12    bool success = fs::equivalent(pathSrc, pathDest);
    13
    14    std::cout << "Result is: " << (int)success << "\n";
    15
    16    // # Case "Both files do not exist"
    17    //
    18    // Exception is thrown:
    19    // 
    20    // terminate called after throwing an instance of 'boost::filesystem::filesystem_error'
    21    //  what():  boost::filesystem::equivalent: Operation not permitted: "/home/user/a.log", "/home/user/b.log"
    22    // Aborted (core dumped)
    23
    24    // # Case "pathSrc exists, pathDest does not"
    25    //
    26    // No exception. Std output is:
    27    // > Result is: 0
    28
    29    // # Case "Both pathSrc and pathDest exist but are different."
    30    //
    31    // No exception. Std output is:
    32    // > Result is: 0    
    33
    34    // # Case "Both pathSrc and pathDest exist and b.log is symlink for a.log." (`ln -s a.log b.log`)
    35    //
    36    // No exception. Std output is:
    37    // > Result is: 0    
    38}
    

    So these samples shows that fs::equivalent behaves similarly in both implementations when compiled using g++.

    And now finally, when I run the sample in Docker:

    0clang++ -stdlib=libc++ --std=c++17 equivalent.cpp17.cpp && ./a.out  # /home/user/a.log EXISTS!
    1
    2// returns:
    3// > terminating with uncaught exception of type std::__1::__fs::filesystem::filesystem_error: filesystem error: in equivalent: Operation not supported [/home/user/a.log] [/home/user/b.log]
    4// > Aborted (core dumped)
    5
    6clang++ --std=c++17 equivalent.cpp17.cpp && ./a.out 
    7// returns:
    8// > Result is: 0
    

    So it looks like -stdlib=libc++ is the culprit or am I missing something? Can anybody verify?

  43. remyers referenced this in commit 2211d05bfd on Jan 26, 2021
  44. in src/test/script_tests.cpp:1732 in 7810d151f5 outdated
    1726@@ -1727,7 +1727,7 @@ BOOST_AUTO_TEST_CASE(script_assets_test)
    1727     bool exists = fs::exists(path);
    1728     BOOST_WARN_MESSAGE(exists, "File $DIR_UNIT_TEST_DATA/script_assets_test.json not found, skipping script_assets_test");
    1729     if (!exists) return;
    1730-    fs::ifstream file(path);
    1731+    std::ifstream file(path);
    1732     BOOST_CHECK(file.is_open());
    


    ryanofsky commented at 4:33 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    Why is this needed? Might be better to revert to keep going through fsbridge


    fanquake commented at 12:30 pm on February 9, 2021:
    Reverted to fsbridge::ifstream.
  45. in src/util/system.cpp:667 in 7810d151f5 outdated
    663@@ -662,7 +664,7 @@ fs::path GetDefaultDataDir()
    664     if (pszHome == nullptr || strlen(pszHome) == 0)
    665         pathRet = fs::path("/");
    666     else
    667-        pathRet = fs::path(pszHome);
    668+        pathRet = fs::u8path(pszHome);
    


    ryanofsky commented at 4:40 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    The change doesn’t seem right and would be good to revert or explain. This is the non-windows section and HOME environment variable and pathRet should both be byte strings with no need to assume any character encoding

  46. in src/util/system.cpp:755 in 7810d151f5 outdated
    702@@ -701,7 +703,7 @@ const fs::path &GetBlocksDir()
    703     if (!path.empty()) return path;
    704 
    705     if (gArgs.IsArgSet("-blocksdir")) {
    706-        path = fs::system_complete(gArgs.GetArg("-blocksdir", ""));
    707+        path = fs::absolute(gArgs.GetArg("-blocksdir", ""));
    


    ryanofsky commented at 4:47 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    If using fs::u8path for -datadir below, probably makes sense to add it here for -blocksdir to be consistent.

    These one-off usages of fs::u8path seem dodgy in general though. Given that c++17 path class doesn’t support an imbue method (https://stackoverflow.com/questions/42765168/change-narrow-string-encoding-or-missing-stdfilesystempathimbue), I think the best thing would be to copy approach in the stackoverflow answer and override the windows fs::path constructor to use fs::u8path automatically. It should be easy to copy the solution there since we already have our own fs namespace.

  47. in src/util/system.cpp:1324 in 7810d151f5 outdated
    1270-    // fs::path, which is then used to explicitly imbue the path.
    1271-    std::locale loc = fs::path::imbue(std::locale::classic());
    1272-#ifndef WIN32
    1273-    fs::path::imbue(loc);
    1274-#else
    1275-    fs::path::imbue(std::locale(loc, new std::codecvt_utf8_utf16<wchar_t>()));
    


    ryanofsky commented at 5:02 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    Mentioned in a previous comment but I think a better workaround for lack of path::imbue than current approach of calling fs::u8path manually would be to use namespace solution from https://stackoverflow.com/questions/42765168/change-narrow-string-encoding-or-missing-stdfilesystempathimbue to call it automatically on windows (and not assume any encoding on other platforms)

  48. in doc/dependencies.md:15 in 9f37a39b11 outdated
    11+| Clang |  | [7.0+](https://releases.llvm.org/download.html) (C++17 & std::filesystem support) |  |  |  |
    12 | Expat | [2.2.7](https://libexpat.github.io/) |  | No | Yes |  |
    13 | fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) |  | No | Yes |  |
    14 | FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) |  | No |  | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) (Android only) |
    15-| GCC |  | [7+](https://gcc.gnu.org/) (C++17 support) |  |  |  |
    16+| GCC |  | [8.1+](https://gcc.gnu.org/) (C++17 & std::filesystem support) |  |  |  |
    


    ryanofsky commented at 5:07 pm on February 5, 2021:

    In commit “build: remove boost::filesystem” (9f37a39b11b240f75b97fb565e6d8cf44972ec49)

    This change seems like it belongs in previous commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7) instead of this one.

  49. in configure.ac:87 in 7810d151f5 outdated
    76@@ -77,6 +77,9 @@ AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
    77 dnl Check if -latomic is required for <std::atomic>
    78 CHECK_ATOMIC
    79 
    80+dnl check if -lstdc++fs is required for std::filesystem
    81+CHECK_FILESYSTEM
    


    ryanofsky commented at 5:09 pm on February 5, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (7810d151f5219e634b431c5393771616c759aef7)

    It would be nice to split this commit up into two commits to separate the build system changes from the c++ code changes. The build system changes can be a first commit and the c++ code changes can be a second commit.

  50. in depends/hosts/darwin.mk:1 in db29710bc1 outdated
    0@@ -1,4 +1,4 @@
    1-OSX_MIN_VERSION=10.14
    2+OSX_MIN_VERSION=10.15
    


    ryanofsky commented at 5:17 pm on February 5, 2021:

    In commit “build: set OSX_MIN_VERSION to 10.15” (db29710bc12f97d9de78fb177322a8ac41f7c87d)

    Would be good to consolidate all the config, makefile, and documentation changes adding build support for std::filesystem into a single atomic commit. Right now they are scattered across three commits and everything seems very mixed up:

    • 7810d151f5219e634b431c5393771616c759aef7 refactor: replace boost::filesystem with std::filesystem (2/5)
    • 9f37a39b11b240f75b97fb565e6d8cf44972ec49 build: remove boost::filesystem (3/5)
    • db29710bc12f97d9de78fb177322a8ac41f7c87d build: set OSX_MIN_VERSION to 10.15 (4/5)

    Better organization would be:

    1. Add std::filesystem build support updating build files & minimum required versions
    2. Switch c++ code from boost::filesystem to std::filesystem
    3. Remove boost::filesystem
  51. ryanofsky approved
  52. ryanofsky commented at 5:27 pm on February 5, 2021: member

    Code review ACK f0667f1d4289b65ac92c70db30e2123179f611e1. No major issues and nothing that couldn’t be fixed later, but:

    • It seems like there might be a macos backupwallet failure: https://cirrus-ci.com/task/5475027611025408?command=ci#L3029. It’s unclear what would cause it, since I wouldn’t expect there to be path handling differences between linux and macos.
    • Windows character set conversion doesn’t seem as robust as it could be (see review comments)
    • Commit organization doesn’t seem as clear as it could be (see review comments)
  53. ryanofsky commented at 5:36 pm on February 5, 2021: member
    Oh, it looks like kiminuo tracked down the wallet_hd backupwallet failure earlier (https://github.com/bitcoin/bitcoin/pull/20744#issuecomment-765467226) to a problem with certain platforms throwing when calling fs::equivalent on non-existent paths. Simple fix might be to define a wrapper function for the affected platforms catching the specific exception or checking for existence before calling fs::equivalent
  54. DrahtBot added the label Needs rebase on Feb 8, 2021
  55. fanquake force-pushed on Feb 9, 2021
  56. fanquake commented at 12:41 pm on February 9, 2021: member
    @ryanofsky thanks for the comments. I’ve reordered and split the commits up more cleanly now. I’ve marked some comments as resolved, however some are still outstanding, and I’m planning on addressing shortly. I’ll also be going back over the discussion in #19245, as i think that contains answers to some queries.
  57. fanquake force-pushed on Feb 9, 2021
  58. fanquake force-pushed on Feb 9, 2021
  59. DrahtBot removed the label Needs rebase on Feb 9, 2021
  60. laanwj referenced this in commit d202054675 on Feb 9, 2021
  61. DrahtBot added the label Needs rebase on Feb 9, 2021
  62. fanquake force-pushed on Feb 10, 2021
  63. fanquake removed the label Needs rebase on Feb 10, 2021
  64. MarcoFalke referenced this in commit f61c3a1090 on Feb 10, 2021
  65. sidhujag referenced this in commit 92f9cd5b8f on Feb 11, 2021
  66. sidhujag referenced this in commit 05c420bf56 on Feb 11, 2021
  67. fanquake force-pushed on Feb 11, 2021
  68. ryanofsky commented at 0:33 am on February 12, 2021: member

    Thanks for updates, commits are simpler now! It looks what’s left to be done are debugging test failures and fixing windows encoding:

    • 32-bit test failure “Value too large for defined data type” from https://cirrus-ci.com/task/4942042640941056 is mysterious, as it seems like it should only happen with really large files https://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Value-too-large-for-defined-data-type which we shouldn’t be creating. Problem happens in many tests, so at least it’s not test-specific.

    • Windows failure “C:/projects/bitcoin/src/test/dbwrapper_tests.cpp(412): error: in “dbwrapper_tests/unicodepath”: check fs::exists(lockPath) has failed” from https://ci.appveyor.com/project/DrahtBot/bitcoin/builds/37725701#L335 looks like a unicode error caused by dropping imbue (see below).

    • Windows walletinit_verify_walletdir_no_trailing2 failure in https://cirrus-ci.com/task/5243515519107072?command=ci#L5082 looks like a broken test that was never testing what the author intended to test. I think the test and “trailing2” map entry could be deleted entirely, ideally in an preceding commit or PR. Also the test setup uses an awkward m_walletdir_path_cases map that seems like it is pointless and just obfuscates test behavior. Maybe that could be removed too.

    • Right now this PR is dropping path imbue, and trying to use ad-hoc u8path calls as a workaround. Earlier comments: #20744 (review), #20744 (review). Manual u8path calls are error-prone and we don’t actually want them on POSIX. (POSIX path strings should be passed straight through to the fs::path constructor without assuming a particular encoding). On windows, we do want u8path calls whenever converting any string to a path. Unlike POSIX, windows natively uses wide strings for arguments, environment variables and paths, so to work correctly on windows we either need to use wide strings internally, or do wide <-> narrow conversions at the borders of windows API interactions. We’ve chosen the latter approach, and can stick with it here by overriding the path(std::string) constructor as described https://stackoverflow.com/questions/42765168/change-narrow-string-encoding-or-missing-stdfilesystempathimbue

  69. DrahtBot added the label Needs rebase on Feb 12, 2021
  70. fanquake force-pushed on Feb 13, 2021
  71. DrahtBot removed the label Needs rebase on Feb 13, 2021
  72. fanquake referenced this in commit 1e4b1973a0 on Feb 15, 2021
  73. fanquake referenced this in commit 1b960f0780 on Feb 15, 2021
  74. fanquake referenced this in commit ffe3d65aaa on Feb 15, 2021
  75. fanquake referenced this in commit 7bf04e358a on Feb 17, 2021
  76. fanquake force-pushed on Feb 17, 2021
  77. laanwj referenced this in commit 04336086d3 on Feb 17, 2021
  78. sidhujag referenced this in commit 5d5698c0ae on Feb 17, 2021
  79. DrahtBot added the label Needs rebase on Feb 19, 2021
  80. fanquake force-pushed on Feb 21, 2021
  81. DrahtBot removed the label Needs rebase on Feb 21, 2021
  82. DrahtBot added the label Needs rebase on Feb 23, 2021
  83. fanquake force-pushed on Mar 11, 2021
  84. DrahtBot removed the label Needs rebase on Mar 11, 2021
  85. kiminuo commented at 2:01 pm on March 30, 2021: contributor

    I attempted to debug the failing ARM test. My debugging efforts led me to this line: https://github.com/fanquake/bitcoin/blob/1bdd927b20fab4aeb5e7119cc298b2a09bf1bc52/src/test/util/setup_common.cpp#L124 which fails with what(): filesystem error: cannot remove all: Value too large for defined data type [...]

    Interestingly, the command fs::remove_all fails even if the folder is empty (I modified it just for fun). It happens always.

  86. MarcoFalke commented at 5:49 pm on March 30, 2021: member
    Does it help if the folder name only contains 128 bit of randomness (as opposed to the 512 bits)?
  87. kiminuo commented at 7:48 pm on March 30, 2021: contributor

    Does it help if the folder name only contains 128 bit of randomness (as opposed to the 512 bits)?

    The error is the same even for /tmp/test_common_Bitcoin_Core/35c where:

    • test_common_Bitcoin Core -> test_common_Bitcoin_Core and
    • 35c is a very short folder name.
    • It does not matter whether I try to remove_all on /tmp/test_common_Bitcoin_Core/35c path or /tmp/test_common_Bitcoin_Core/35c/ path (see the trailing slash).

    So this does not seem to be the issue.

    I have also tried to copy /tmp/test_common_Bitcoin_Core/35c to /home/user/bitcoin/bitcoin/ci/scratch/out/arm-linux-gnueabihf and delete that folder and it does not work too so it’s not about /tmp.

    At this point, it looks like it does not work at all for directories (full or empty). However, deleting /home/user/bitcoin/bitcoin/ci/scratch/out/arm-linux-gnueabihf/35c/test.txt (i.e. a file) finished without an error when deleted with fs::remove_all(path).

    (btw: Is this https://github.com/gcc-mirror/gcc/commits/releases/gcc-8/libstdc%2B%2B-v3/src/filesystem/ops.cc useful? arm-linux-gnueabihf-g++ --version reports arm-linux-gnueabihf-g++ (Debian 8.3.0-2) 8.3.0)

  88. ryanofsky commented at 5:03 pm on March 31, 2021: member

    The “cannot remove all: Value too large for defined data type” bug mentioned

    seems to be reported externally https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93201. Probably easiest workaround is just to avoid remove_all and write a simple recursive remove function.

    The remaining errors seem unicode related and probably fixed by implementing the suggested imbue workaround.

  89. kiminuo commented at 9:00 am on April 1, 2021: contributor

    @ryanofsky I have narrowed the failing ARM issue down to:

    0auto iterator = fs::directory_iterator(m_path_root); // where m_path_root = /tmp/test_common_Bitcoin Core/29248e247aad6a68595f5e097d311e923c00300291f160ee2254ed8b5b4668c4
    

    which throws:

    0/tmp/test_common_Bitcoin Core/29248e247aad6a68595f5e097d311e923c00300291f160ee2254ed8b5b4668c4
    1terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
    2  what():  filesystem error: directory iterator cannot open directory: Value too large for defined data type [/tmp/test_common_Bitcoin Core/29248e247aad6a68595f5e097d311e923c00300291f160ee2254ed8b5b4668c4]
    

    Interestingly

    0auto status = fs::status(m_path_root);
    

    does not throw.

  90. MarcoFalke commented at 9:43 am on April 1, 2021: member
    The gcc bug is fixed on all branches, but is seems that gcc for arm on debian buster didn’t receive the patch? This should be a relative edge-case platform and I think we can just bump the ci config from buster to bullseye to fix the problem. (It does fix it for me locally).
  91. kiminuo commented at 10:50 am on April 1, 2021: contributor

    The gcc bug is fixed on all branches, but is seems that gcc for arm on debian buster didn’t receive the patch?

    Might be so.

    This should be a relative edge-case platform and I think we can just bump the ci config from buster to bullseye to fix the problem. (It does fix it for me locally).

    Bullseye is not stable yet. Maybe gcc-9 instead of gcc-8 on buster would suffice here to be less aggressive in version bumps? Anyway, I’m kind of worried that this would mean to delay this PR by a Bitcoin Core version or two.

  92. MarcoFalke added this to the milestone 23.0 on Apr 1, 2021
  93. MarcoFalke commented at 11:05 am on April 1, 2021: member

    Assigned the 23.0 milestone, because rushing this into 0.22 might be too aggressive. See also #20460 (comment)

    In a year from now (when this is going to be releases), debian:buster may have bumped the gcc-8 to include the fix, or bullseye may have been released as stable. So I think re-implementing std::fs features in our code base is not needed.

  94. laanwj commented at 11:49 am on April 1, 2021: member

    So I think re-implementing std::fs features in our code base is not needed.

    Agree on the general idea. It is slightly disappointing but there is no rush. If time will solve the issues automatically there is no need to spend work and reviewer time on doing some in-between thing.

  95. MarcoFalke commented at 11:55 am on April 1, 2021: member
    Branch-off is in only 3 months, so I think it is fine to drink some tea in the meantime and wait a bit
  96. fanquake force-pushed on Apr 1, 2021
  97. kiminuo commented at 12:12 pm on April 2, 2021: contributor

    This is probably useful for the Win64 test failure:

     0// Run with: x86_64-w64-mingw32-g++ --std=c++17 --static paths.cpp17.cpp && wine ./a.exe
     1// For comparison: g++ --std=c++17 --static paths.cpp17.cpp && ./a.out
     2
     3#include <string>
     4#include <iostream>
     5#include <filesystem>
     6namespace fs = std::filesystem;
     7
     8int main()
     9{
    10    // Basically copied from init_test_fixture.cpp:
    11    fs::path m_cwd = fs::current_path();
    12
    13    std::string sep;
    14    sep += fs::path::preferred_separator;
    15
    16    fs::path m_datadir = fs::current_path();
    17
    18    fs::path default_path = m_cwd / "wallets";
    19    fs::path custom = m_datadir / "my_wallets";
    20    fs::path nonexistent = m_datadir / "path_does_not_exist";
    21    fs::path file = m_datadir / "not_a_directory.dat";
    22    fs::path trailing = m_datadir / "wallets" / sep;
    23
    24    // *sep* is "appended" and not "concatenated".
    25    // https://en.cppreference.com/w/cpp/filesystem/path/append
    26    // https://en.cppreference.com/w/cpp/filesystem/path/concat
    27    fs::path trailing2 = m_datadir / "wallets" / sep / sep;
    28
    29    std::cout << "default path: " << default_path << "\n";
    30    std::cout << "custom: " << custom << "\n";
    31    std::cout << "nonexistent: " << nonexistent << "\n";
    32    std::cout << "file: " << file << "\n";
    33    std::cout << "trailing: " << trailing << "\n";
    34    std::cout << "trailing2: " << trailing2 << "\n";
    35
    36    // Demonstrates "+=" behavior
    37    fs::path trailing_plus = m_datadir / "wallets";
    38    trailing_plus += sep;
    39
    40    std::cout << "trailing_plus: " << trailing_plus << "\n";
    41    std::cout << "absolute(trailing_plus): " << fs::absolute(trailing_plus) << "\n";
    42    std::cout << "canonical(trailing_plus): " << fs::canonical(trailing_plus) << "\n"; // Directory must exist! Otherwise an exception is thrown.
    43
    44    // See "normalize algorithm" here: https://en.cppreference.com/w/cpp/filesystem/path 
    45    std::cout << "trailing_plus.lexically_normal(): " << trailing_plus.lexically_normal() << "\n";
    46
    47    std::cout << "end\n"; // breakpoint line :)
    48}
    
     0default path: "Z:\\home\\user\\bitcoin\\wallets"
     1custom: "Z:\\home\\user\\bitcoin\\my_wallets"
     2nonexistent: "Z:\\home\\user\\bitcoin\\path_does_not_exist"
     3file: "Z:\\home\\user\\bitcoin\\not_a_directory.dat"
     4trailing: "Z:\\"
     5trailing2: "Z:\\"
     6trailing_plus: "Z:\\home\\user\\bitcoin\\wallets\\"
     7absolute(trailing_plus): "Z:\\home\\user\\bitcoin\\wallets\\"
     8canonical(trailing_plus): "Z:\\home\\user\\bitcoin\\wallets"
     9trailing_plus.lexically_normal(): "Z:\\home\\user\\bitcoin\\wallets\\"
    10end
    
     0default path: "/home/bitcoin/wallets"
     1custom: "/home/bitcoin/my_wallets"
     2nonexistent: "/home/bitcoin/path_does_not_exist"
     3file: "/home/bitcoin/not_a_directory.dat"
     4trailing: "/"
     5trailing2: "/"
     6trailing_plus: "/home/bitcoin/wallets/"
     7absolute(trailing_plus): "/home/bitcoin/wallets/"
     8canonical(trailing_plus): "/home/bitcoin/wallets"
     9trailing_plus.lexically_normal(): "/home/bitcoin/wallets/"
    10end
    
  98. DrahtBot added the label Needs rebase on Apr 13, 2021
  99. theStack commented at 3:13 pm on April 18, 2021: member
    Concept ACK Will test on Linux and also OpenBSD soon (let’s see if there are any issues on FFS2).
  100. promag commented at 9:54 am on May 15, 2021: member
    Concept ACK.
  101. hebasto commented at 10:23 am on May 15, 2021: member
    Concept ACK.
  102. fanquake force-pushed on May 17, 2021
  103. DrahtBot removed the label Needs rebase on May 17, 2021
  104. DrahtBot added the label Needs rebase on Jun 17, 2021
  105. fanquake force-pushed on Jun 24, 2021
  106. DrahtBot removed the label Needs rebase on Jun 24, 2021
  107. fanquake force-pushed on Jun 24, 2021
  108. kiminuo commented at 7:18 pm on June 24, 2021: contributor

    Regarding Android CI error: Currently, Android NDK 21 is used in the master branch, but Android NDK 22 is necessary for std::filesystem support.

    Qt works with Android NDK 21 but not with NDK 22 out of the box - it did not work for me and I’m not sure how to fix it, build gurus here will understand it much better.

  109. hebasto commented at 11:54 pm on June 24, 2021: member

    Qt works with Android NDK 21 but not with NDK 22 out of the box - it did not work for me and I’m not sure how to fix it, build gurus here will understand it much better.

    See #22074.

  110. kiminuo commented at 9:34 am on June 25, 2021: contributor

    Qt works with Android NDK 21 but not with NDK 22 out of the box - it did not work for me and I’m not sure how to fix it, build gurus here will understand it much better.

    See #22074.

    Thank you. That’s the error I can see.

  111. DrahtBot added the label Needs rebase on Jun 28, 2021
  112. fanquake referenced this in commit 7fc9a45f47 on Jul 21, 2021
  113. fanquake force-pushed on Jul 21, 2021
  114. fanquake commented at 7:50 am on July 21, 2021: member
    Now that we’ve branch of for 22.x, we can actually think about merging this. I’ve rebased on master (which should fix the Android build issues) and included some more changes from @kiminuo. That should mean that what’s left to finish up here is the Windows changes, which I’d like to get to shortly.
  115. DrahtBot removed the label Needs rebase on Jul 21, 2021
  116. hebasto commented at 8:25 am on July 21, 2021: member

    That should mean that what’s left to finish up here is the Windows changes, which I’d like to get to shortly.

    As this pr discussion is pretty long, here are Windows related comments in one place:

  117. hebasto commented at 8:49 am on July 21, 2021: member

    748a989fffa2f86876c366f6c3a58637e8588be8 “build: set OSX_MIN_VERSION to 10.15”

    This is required to use std::filesystem on macOS.

    Documented in Xcode 11 Release Notes.

  118. hebasto commented at 9:06 am on July 21, 2021: member

    748a989fffa2f86876c366f6c3a58637e8588be8 “build: set OSX_MIN_VERSION to 10.15”

    Here’re other places where the version 10.14 should be updated/dropped:

    0$ git grep -n -e '10\.14' -- ':(exclude)doc/release-notes/*'
    1contrib/devtools/test-symbol-check.py:139:        self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,10.14', '-Wl,11.4']),
    2doc/build-osx.md:118:Note: Apple has included a useable `sqlite` package since macOS 10.14.
    3doc/release-notes.md:51:using the Linux kernel, macOS 10.14+, and Windows 7 and newer.  Bitcoin
    4doc/release-notes.md:56:From Bitcoin Core 22.0 onwards, macOS versions earlier than 10.14 are no longer supported.
    5share/qt/Info.plist.in:6:  <string>10.14.0</string>
    
  119. MarcoFalke added the label DrahtBot Guix build requested on Jul 21, 2021
  120. hebasto commented at 9:38 am on July 21, 2021: member
    Approach ACK c5c3d5de39ee80aad8fa0c7700d42a872c11c225.
  121. sidhujag referenced this in commit 3791bad84f on Jul 23, 2021
  122. DrahtBot commented at 11:17 am on July 24, 2021: member

    Guix builds

    File commit 36aee0f3538ec3399a3838041ea5993aba5f518b(master) commit 4bd690d8c420268f4ed7fa3063822b0c9f4cc30c(master and this pull)
    SHA256SUMS.part ee8f2fe0439aa065... 52af71c12089c1e0...
    SKIPATTEST.TAG e3b0c44298fc1c14... e3b0c44298fc1c14...
    *-aarch64-linux-gnu-debug.tar.gz 562dfed93e39da07... 805db70ac634759e...
    *-aarch64-linux-gnu.tar.gz 6f4112944cf81e33... 83ea1e8111efd567...
    *-arm-linux-gnueabihf-debug.tar.gz 8f37daef2ac0bdec... 2f2920b32d050732...
    *-arm-linux-gnueabihf.tar.gz 2cb234fda6084d80... ce977b7a3b7b9b2e...
    *-osx-unsigned.dmg ae6190e1c9422ccc...
    *-osx-unsigned.tar.gz 20d9d3e908299ee1...
    *-osx64.tar.gz ab781ed522c81dad...
    *-powerpc64-linux-gnu-debug.tar.gz 94dc3a358b093190... d78aaddcde2a0d4d...
    *-powerpc64-linux-gnu.tar.gz be3ddea1275caec5... 07ac927afe2d60d1...
    *-powerpc64le-linux-gnu-debug.tar.gz 8b6559d4c3a13aea... d8f731849ddf29a6...
    *-powerpc64le-linux-gnu.tar.gz 07eee5b417dd60c2... 9a2b7779711cebb8...
    *-riscv64-linux-gnu-debug.tar.gz 897e2b442724eda7... 6dc21a70f9859c1f...
    *-riscv64-linux-gnu.tar.gz 1ca2ee8b38397ce3... 53e90f196637b6ee...
    *-win-unsigned.tar.gz 9137ddedd3649f6d...
    *-win64-debug.zip cc652316d6a8c470...
    *-win64-setup-unsigned.exe 34309929018670ba...
    *-win64.zip 9252470a33cec985...
    *-x86_64-linux-gnu-debug.tar.gz 0ef500b68df2258e... d69c0b1414233b15...
    *-x86_64-linux-gnu.tar.gz 828f789f13e447bb... 9465aedaf2cb3ed9...
    *.tar.gz 756fc6a1bafc8081... eadc655850655947...
    guix_build.log 52af8deb0ec28951... e9090ac9fb663f7e...
    guix_build.log.diff 462ecdf44896886a...
  123. DrahtBot removed the label DrahtBot Guix build requested on Jul 24, 2021
  124. MarcoFalke commented at 5:43 pm on July 24, 2021: member
     0+ env CONFIG_SITE=/bitcoin/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking --enable-reduce-exports --disable-bench --disable-gui-tests --disable-fuzz-binary 'CFLAGS=-O2 -g -fno-ident' 'CXXFLAGS=-O2 -g -fno-ident' LDFLAGS=-Wl,--no-insert-timestamp
     1configure: loading site script /bitcoin/depends/x86_64-w64-mingw32/share/config.site
     2checking for x86_64-w64-mingw32-pkg-config... /root/.guix-profile/bin/pkg-config --static
     3checking pkg-config is at least version 0.9.0... yes
     4checking build system type... x86_64-pc-linux-gnu
     5checking host system type... x86_64-w64-mingw32
     6checking for a BSD-compatible install... /root/.guix-profile/bin/install -c
     7checking whether build environment is sane... yes
     8checking for x86_64-w64-mingw32-strip... x86_64-w64-mingw32-strip
     9checking for a thread-safe mkdir -p... /root/.guix-profile/bin/mkdir -p
    10checking for gawk... gawk
    11checking whether make sets $(MAKE)... yes
    12checking whether make supports nested variables... yes
    13checking whether to enable maintainer-specific portions of Makefiles... no
    14checking whether make supports nested variables... (cached) yes
    15checking whether the C++ compiler works... yes
    16checking for C++ compiler default output file name... a.exe
    17checking for suffix of executables... .exe
    18checking whether we are cross compiling... yes
    19checking for suffix of object files... o
    20checking whether we are using the GNU C++ compiler... yes
    21checking whether x86_64-w64-mingw32-g++ accepts -g... yes
    22checking whether make supports the include directive... yes (GNU style)
    23checking dependency style of x86_64-w64-mingw32-g++... none
    24checking whether x86_64-w64-mingw32-g++ supports C++17 features with -std=c++17... yes
    25checking whether std::atomic can be used without link library... yes
    26checking whether std::filesystem can be used without link library... no
    27checking whether std::filesystem needs -lstdc++fs... no
    28configure: error: in `/distsrc-base/distsrc-4bd690d8c420-x86_64-w64-mingw32':
    29configure: error: cannot figure out how to use std::filesystem
    30See `config.log' for more details
    
  125. DrahtBot added the label Needs rebase on Aug 20, 2021
  126. MarcoFalke commented at 9:02 am on August 27, 2021: member
  127. fanquake force-pushed on Aug 31, 2021
  128. fanquake commented at 2:40 am on August 31, 2021: member

    Rebased.

    Here’re other places where the version 10.14 should be updated/dropped:

    Updated those that were relevant.

    Can remove this: https://github.com/bitcoin/bitcoin/pull/20586/files#r656885645

    Included.

    Note that progress is still being made here. Someone else is currently looking at the Windows portion of the changes.

  129. fanquake renamed this:
    [POC] Use std::filesystem. Remove Boost Filesystem & System
    Use std::filesystem. Remove Boost Filesystem & System
    on Aug 31, 2021
  130. fanquake removed the label Needs rebase on Aug 31, 2021
  131. dongcarl commented at 8:18 pm on September 1, 2021: member
    Concept ACK
  132. DrahtBot added the label Needs rebase on Sep 2, 2021
  133. fanquake force-pushed on Sep 2, 2021
  134. DrahtBot removed the label Needs rebase on Sep 2, 2021
  135. DrahtBot added the label Needs rebase on Sep 7, 2021
  136. fanquake force-pushed on Sep 8, 2021
  137. DrahtBot removed the label Needs rebase on Sep 8, 2021
  138. hebasto commented at 4:34 pm on September 8, 2021: member

    In the commit “build: set OSX_MIN_VERSION to 10.15” (edeed577501693e0b8e8f0c8c5d1ccdc47587557) the following change is also required:

     0--- a/contrib/devtools/symbol-check.py
     1+++ b/contrib/devtools/symbol-check.py
     2@@ -217,7 +217,7 @@ def check_MACHO_libraries(filename) -> bool:
     3 
     4 def check_MACHO_min_os(filename) -> bool:
     5     binary = lief.parse(filename)
     6-    if binary.build_version.minos == [10,14,0]:
     7+    if binary.build_version.minos == [10,15,0]:
     8         return True
     9     return False
    10 
    
  139. kiminuo commented at 8:04 am on September 9, 2021: contributor

    On native Win64 the only test fails:

    https://github.com/bitcoin/bitcoin/blob/5e3380b9f59481fc18e05b9d651c3c733abe4053/src/test/dbwrapper_tests.cpp#L401-L412

    Could be related to #17641, google/leveldb#755, google/leveldb#760

    Some observations, maybe it helps somebody to fix the issue:

    Setting locale

    Adding std::setlocale(LC_ALL, "en_US.UTF-8"); makes the test pass.

    Original test

     0BOOST_AUTO_TEST_CASE(unicodepath)
     1{
     2    // Attempt to create a database with a UTF8 character in the path.
     3    // On Windows this test will fail if the directory is created using
     4    // the ANSI CreateDirectoryA call and the code page isn't UTF8.
     5    // It will succeed if created with CreateDirectoryW.
     6    fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644";
     7    CDBWrapper dbw(ph, (1 << 20));
     8
     9    fs::path lockPath = ph / "LOCK";
    10    BOOST_CHECK(fs::exists(lockPath));
    11}
    

    My Visual Studio debugger shows that path fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644"; is garbled once created. Likely "test_runner_₿_🏃_20191128_104644" is intepreted using some some local codepage.

    Modified test with euro sign

    (No pun intended :))

     0BOOST_AUTO_TEST_CASE(unicodepath)
     1{
     2    // Attempt to create a database with a UTF8 character in the path.
     3    // On Windows this test will fail if the directory is created using
     4    // the ANSI CreateDirectoryA call and the code page isn't UTF8.
     5    // It will succeed if created with CreateDirectoryW.
     6    // fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644"; // REMOVED
     7    fs::path ph = m_args.GetDataDirBase() / L"test_runner_€_20191128_104644"; // ADDED
     8    CDBWrapper dbw(ph, (1 << 20));
     9
    10    fs::path lockPath = ph / "LOCK";
    11    BOOST_CHECK(fs::exists(lockPath));
    12}
    

    This test leads on my computer to creating of two folders in C:\Users\kimi\AppData\Local\Temp\test_common_Bitcoin Core\efd602083fe69783d5e6eff1220a12770bd2168d338ae233e260bae6a10c6068:

    • test_runner_�_20191128_104644
    • test_runner_€_20191128_104644

    was used because it can be represented by two bytes.

    Note that using L"test_runner_₿_🏃_20191128_104644" leads to class std::system_error: No mapping for the Unicode character exists in the target multi-byte code page. error which seems to make sense to me.

    std::filesystem::u8path

    I had no success with this method really.

    (https://stackoverflow.com/questions/30829364/open-utf8-encoded-filename-in-c-windows/69037041#69037041)

  140. hebasto commented at 9:04 am on September 9, 2021: member
    My own research confirms @kiminuo’s one.
  141. hebasto commented at 11:29 am on September 9, 2021: member

    Adding std::setlocale(LC_ALL, "en_US.UTF-8"); makes the test pass.

    From MS docs:

    Interconversions between these [pathname] representations are mediated, as needed, by the use of one or more codecvt facets. If no specific locale object is specified, these facets are obtained from the global locale.

  142. hebasto commented at 12:36 pm on September 9, 2021: member
    Recently added to Windows CI task functional tests are broken with this branch.
  143. fanquake force-pushed on Sep 9, 2021
  144. hebasto commented at 2:40 pm on September 9, 2021: member

    Win64 CI task failed due to an unrelated issue:

    0https://github.com/PowerShell/PowerShell/releases/download/v7.1.0/PowerShell-7.1.0-win-x86.zip: WinHttpReceiveResponse() failed: 12030
    

    so going to re-run it.

  145. in src/test/dbwrapper_tests.cpp:408 in 56f9476619 outdated
    403@@ -404,6 +404,7 @@ BOOST_AUTO_TEST_CASE(unicodepath)
    404     // On Windows this test will fail if the directory is created using
    405     // the ANSI CreateDirectoryA call and the code page isn't UTF8.
    406     // It will succeed if created with CreateDirectoryW.
    407+    std::setlocale(LC_ALL, "en_US.UTF-8");
    


    MarcoFalke commented at 2:42 pm on September 9, 2021:

    might need

    0#include <clocale>
    

    hebasto commented at 2:44 pm on September 9, 2021:

    and

    0--- a/test/lint/lint-locale-dependence.sh
    1+++ b/test/lint/lint-locale-dependence.sh
    2@@ -44,6 +44,7 @@ KNOWN_VIOLATIONS=(
    3     "src/node/blockstorage.cpp:.*atoi"
    4     "src/qt/rpcconsole.cpp:.*atoi"
    5     "src/rest.cpp:.*strtol"
    6+    "src/test/dbwrapper_tests.cpp:.*setlocale"
    7     "src/test/dbwrapper_tests.cpp:.*snprintf"
    8     "src/test/fuzz/locale.cpp"
    9     "src/test/fuzz/parse_numbers.cpp:.*atoi"
    

    fanquake commented at 3:20 am on September 10, 2021:
    added & added

    ryanofsky commented at 9:49 pm on October 18, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    These changes are not going to have any useful effect on dbwrapper after #22937, so should be reverted now. leveldb is expecting a UTF8 string on windows, that’s what #22937 already passes.

    Suggested change:

     0diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp
     1index a6ac3a33533..b6f5938892c 100644
     2--- a/src/test/dbwrapper_tests.cpp
     3+++ b/src/test/dbwrapper_tests.cpp
     4@@ -6,7 +6,6 @@
     5 #include <test/util/setup_common.h>
     6 #include <uint256.h>
     7 
     8-#include <clocale>
     9 #include <memory>
    10 
    11 #include <boost/test/unit_test.hpp>
    12@@ -405,7 +404,6 @@ BOOST_AUTO_TEST_CASE(unicodepath)
    13     // On Windows this test will fail if the directory is created using
    14     // the ANSI CreateDirectoryA call and the code page isn't UTF8.
    15     // It will succeed if created with CreateDirectoryW.
    16-    std::setlocale(LC_ALL, "en_US.UTF-8");
    17     fs::path ph = m_args.GetDataDirBase() / "test_runner_₿_🏃_20191128_104644";
    18     CDBWrapper dbw(ph, (1 << 20));
    19 
    20diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh
    21index 1e7d04ad26e..b119cffec80 100755
    22--- a/test/lint/lint-locale-dependence.sh
    23+++ b/test/lint/lint-locale-dependence.sh
    24@@ -42,7 +42,6 @@ export LC_ALL=C
    25 # TODO: Reduce KNOWN_VIOLATIONS by replacing uses of locale dependent snprintf with strprintf.
    26 KNOWN_VIOLATIONS=(
    27     "src/dbwrapper.cpp:.*vsnprintf"
    28-    "src/test/dbwrapper_tests.cpp:.*setlocale"
    29     "src/test/dbwrapper_tests.cpp:.*snprintf"
    30     "src/test/fuzz/locale.cpp"
    31     "src/test/fuzz/string.cpp"
    
  146. ryanofsky commented at 9:04 pm on September 9, 2021: member

    I didn’t really get an chance to test and finish test this yet, but here is my attempt at improving the encoding situation on windows using the path(std::string) constructor override I mentioned earlier: 099e0207808687e3af2148e7c31353677b866d72 (branch)

    References:

    I also see there are a lot of path::string() calls that should probably be replaced by path::u8string() calls for logging / rpc / display purposes, but this would be another followup

  147. fanquake force-pushed on Sep 10, 2021
  148. fanquake commented at 3:23 am on September 10, 2021: member

    I’m seeing functional test failures on macOS again due to differences in paths /var/ vs /private/var, where the former is a symlink to the later. I have a recollection of seeing this previously, and thought we’d fixed/worked around it.

    I didn’t really get an chance to test and finish test this yet, but here is my attempt at improving the encoding situation on windows using the path(std::string) constructor override I mentioned earlier: 099e020 (branch)

    Thanks. I’ll take a look at testing / including this shortly.

    One other thing we’ll likely need to do here is move Guix to using a newer version of mingw-w64. iirc we’re currently using 7, but I’m pretty sure we’ll required 8, which is available in Guix. cc @dongcarl.

  149. ryanofsky commented at 4:45 am on September 10, 2021: member

    I had second thoughts about the path(std::string) constructor approach I was trying above. I think it adds to much magic. Better not to make a custom path class that differs subtly from the standard path class on windows, just to be able to do magic implicit conversions, when explicit conversions would be clearer anyway. So starting over.


    Windows encoding bugfix, attempt 2

    Summary

    The implicit path <=> std::string conversions done by the std::filesystem::path(std::string) constructor and std::filesystem::path::string() method generally work well on linux, but are unsafe and broken for our purposes on Windows. Solution is to disable these methods and start using safer, more explicit path <=> std::string conversion functions instead.

    Details

    On POSIX, paths natively are 8-bit strings that do not specify any particular encoding, so they can be straightforwardly converted to and from std::string objects with no transformations. On Windows, paths natively are unicode strings that have to be encoded or decoded in some way to be represented in std::string objects. Ideally, the way we would convert paths to std::string is by encoding them as UTF-8 (technically a “wobbly” variation of UTF-8 to handle some edge cases). This is what the previous boost path class did after imbueing it with a locale. But with the new std::filesystem::path class, imbueing a locale is not possible. So the standard path(std::string) constructor and path::string() methods will no longer use UTF-8. Instead they will use different encodings depending on the local system’s current code page which makes these functions unsafe and useless for our purposes. In Windows versions since May 2019 it is possible to change the build in a way that would make these functions always use UTF-8. But if we want to keep providing the same behavior and level of compatibility that we had with boost we need to stop using calling these functions and start doing explicit conversions. So I think the simplest and best way forward is just to prevent the bad string functions from being called, and to update the calling code to use explicit conversions. I implemented this here: 3e88c9f6b4e84ab5da78f4862266b5ff13bb8fc0 (tag)

    It’s kind of a big commit, but the majority of it is just introducing and calling new PathToString and PathFromString functions and I can easily split it out into a standalone PR that does not depend on anything else here.

  150. kiminuo commented at 6:10 am on September 10, 2021: contributor
    @ryanofsky The unicodepath test passes for me on Windows 10 with your patch (3e88c9f (tag)). Nice work.
  151. ryanofsky referenced this in commit 1e07139279 on Sep 10, 2021
  152. ryanofsky referenced this in commit ddbfc51002 on Sep 10, 2021
  153. ryanofsky referenced this in commit a7f5053ca3 on Sep 10, 2021
  154. ryanofsky referenced this in commit d312e529ce on Sep 10, 2021
  155. ryanofsky commented at 7:43 pm on September 13, 2021: member
    I posted a version of this PR rebased on top of #22937 here: e03ede894b86c793a33e84eade230c35d35457df, (tag)
  156. hebasto commented at 7:47 pm on September 13, 2021: member

    I posted a version of this PR rebased on top of #22937 here: e03ede8, (tag)

    Testing…

  157. hebasto commented at 0:49 am on September 15, 2021: member

    I posted a version of this PR rebased on top of #22937 here: e03ede8, (tag)

    The version with green CI for the Windows MSVC build is here:

  158. fanquake referenced this in commit a7bb3a8152 on Sep 16, 2021
  159. fanquake referenced this in commit 252d1a70fb on Sep 16, 2021
  160. MarcoFalke referenced this in commit 87780dfee8 on Sep 16, 2021
  161. ryanofsky commented at 4:04 pm on September 16, 2021: member

    #22937 was updated with fixes above. Rebased version of this PR after that one is: aeabf62ae14a0a281ffc865bfd4975ba65be9419 (tag)


    EDIT: Updated again to fix CI issue: 8f015cb0679217ec83db36954b3751223f3bbfb6 (tag)

  162. DrahtBot added the label Needs rebase on Sep 16, 2021
  163. fanquake referenced this in commit 8f022a59b8 on Sep 21, 2021
  164. in doc/dependencies.md:10 in 2779599a56 outdated
     6@@ -7,11 +7,11 @@ These are the dependencies currently used by Bitcoin Core. You can find instruct
     7 | --- | --- | --- | --- | --- | --- |
     8 | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No |  |  |
     9 | Boost | [1.71.0](https://www.boost.org/users/download/) | [1.64.0](https://github.com/bitcoin/bitcoin/pull/22320) | No |  |  |
    10-| Clang<sup>[ \* ](#note1)</sup> |  | [5.0+](https://releases.llvm.org/download.html) (C++17 support) |  |  |  |
    11+| Clang<sup>[ \* ](#note1)</sup> |  | [7.0+](https://releases.llvm.org/download.html) (C++17 & std::filesystem support) |  |  |  |
    


    MarcoFalke commented at 8:22 am on September 21, 2021:
    in the doc commit: Does #22339 also need to be updated?

    fanquake commented at 8:23 am on September 21, 2021:
    Gunna split more of this out. Will address.
  165. fanquake force-pushed on Sep 21, 2021
  166. fanquake commented at 11:54 pm on September 21, 2021: member
    Rebased this after #22994 & #22993. Going to split out a couple more of the commits here shortly.
  167. DrahtBot removed the label Needs rebase on Sep 22, 2021
  168. in test/functional/wallet_multiwallet.py:144 in 1d992d4079 outdated
    140@@ -141,7 +141,7 @@ def wallet_file(name):
    141 
    142         # should raise rpc error if wallet path can't be created
    143         err_code = -4 if self.options.descriptors else -1
    144-        assert_raises_rpc_error(err_code, "boost::filesystem::create_directory:", self.nodes[0].createwallet, "w8/bad")
    145+        assert_raises_rpc_error(err_code, "filesystem error:", self.nodes[0].createwallet, "w8/bad")
    


    hebasto commented at 10:11 pm on September 26, 2021:

    1c655826850235fbf13dc90daf66e2b3facdc9ba

    MSVC implementation of std::filesystem has different error messages:

    0        assert_raises_rpc_error(err_code, "filesystem error:" if sys.platform != 'win32' else "create_directories:", self.nodes[0].createwallet, "w8/bad")
    

    (and import sys, of course).


    MarcoFalke commented at 6:24 am on September 27, 2021:
    Wouldn’t it make more sense to use EXEEXT to avoid issues when the tests are run in wine or so?
  169. fanquake referenced this in commit 67eae69f3f on Sep 28, 2021
  170. fanquake force-pushed on Sep 28, 2021
  171. fanquake commented at 6:12 am on September 28, 2021: member
    Rebased after the merge of #23060. All prerequisites that were part of this PR have now been merged. The next step to moving to std::filesystem should be #22937.
  172. in test/lint/lint-includes.sh:58 in a073a2f6fd outdated
    53@@ -54,8 +54,6 @@ EXPECTED_BOOST_INCLUDES=(
    54     boost/algorithm/string/replace.hpp
    55     boost/algorithm/string/split.hpp
    56     boost/date_time/posix_time/posix_time.hpp
    57-    boost/filesystem.hpp
    58-    boost/filesystem/fstream.hpp
    


    hebasto commented at 12:41 pm on September 28, 2021:
    Removing of boost/filesystem/fstream.hpp should be done in the “refactor: replace boost::filesystem with std::filesystem” commit (5fb92bab5f8c6c07bb668d7a7f2203f389a4956d) to let it pass test/lint/lint-includes.sh.
  173. fanquake force-pushed on Sep 29, 2021
  174. fanquake commented at 2:39 am on September 29, 2021: member

    I’ve modified the std::filesystem macro to try using -lc++fs if -lstdc++fs doesn’t work. Should fix the issues in the nowallet CI, which uses Clang 7 and libc++.

    Removing of boost/filesystem/fstream.hpp should be done in the

    Done.

  175. hebasto commented at 10:25 pm on September 29, 2021: member

    That should mean that what’s left to finish up here is the Windows changes, which I’d like to get to shortly.

    Any update about cross-compiling for Windows?

  176. dongcarl commented at 9:24 pm on October 5, 2021: member

    One other thing we’ll likely need to do here is move Guix to using a newer version of mingw-w64. iirc we’re currently using 7, but I’m pretty sure we’ll required 8, which is available in Guix. cc @dongcarl.

    I’m not sure upgrading to mingw-w64 v8 will affect anything, could you link me to the specific failure that makes you think this is required?

  177. fanquake commented at 10:23 am on October 7, 2021: member

    Any update about cross-compiling for Windows?

    I’m not sure upgrading to mingw-w64 v8 will affect anything, could you link me to the specific failure that makes you think this is required?

    Discussed with @dongcarl, and lstdc++fs is missing because we don’t yet compile our Guix GCC with --enable-libstdcxx-filesystem-ts, i.e similar to what Debian does for it’s mingw-w64 package, and support for std::filesystem was only turned on by default for mingw-w64 starting with GCC-10, see https://github.com/gcc-mirror/gcc/commit/f0cfae9f4efdb8a0a5bb61b7a739350d992afc3f.

    While the GCC release notes claim that, (incomplete) support for std::filesystem only landed in GCC-9:

    Runtime Library (libstdc++) Incomplete support for the C++17 Filesystem library and the Filesystem TS on Windows.

    it’s not clear that’s actually the case, as you can use <filesystem> with a GCC 8.3 backed mingw-w64 6.0.0 on Debian Buster (with -lstdc++fs).

  178. fanquake force-pushed on Oct 11, 2021
  179. DrahtBot added the label Needs rebase on Oct 12, 2021
  180. fanquake force-pushed on Oct 13, 2021
  181. fanquake force-pushed on Oct 13, 2021
  182. DrahtBot removed the label Needs rebase on Oct 13, 2021
  183. laanwj referenced this in commit 1884ce2f4c on Oct 15, 2021
  184. DrahtBot added the label Needs rebase on Oct 15, 2021
  185. fanquake force-pushed on Oct 16, 2021
  186. fanquake commented at 7:32 am on October 16, 2021: member
    I’ve rebased to account for #22937 added a commit for Guix to pass --enable-libstdcxx-filesystem-ts=yes to our mingw GCC build. However libstdc++ is failing to build it’s filesystem component. @dongcarl could you take a look? The full GCC build output is here: https://gist.github.com/fanquake/c040358952075b054cda7786e3e98563.
  187. fanquake force-pushed on Oct 16, 2021
  188. DrahtBot removed the label Needs rebase on Oct 16, 2021
  189. in src/fs.h:25 in 6316193878 outdated
    37- * method, which worked well in the boost::filesystem implementation, but have
    38- * unsafe and unpredictable behavior on Windows in the std::filesystem
    39- * implementation (see implementation note in \ref PathToString for details).
    40+ * Path class wrapper to blocks calls to the fs::path(std::string) implicit
    41+ * constructor and the fs::path::string() method, which worked well in the
    42+ * boost::filesystem implementation, but have unsafe and unpredictable behavior
    


    ryanofsky commented at 5:38 pm on October 16, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    I think it would be good to simplify

    which worked well in the boost::filesystem implementation but have unsafe and unpredictable behavior on Windows in the std::filesystem implementation

    to just

    which have unsafe and unpredictable behavior on Windows

    because the boost comparison is no longer relevant after this PR.


    fanquake commented at 4:13 am on October 21, 2021:
    Changed in next push.
  190. in src/fs.h:72 in e4d50b8f03 outdated
    81 
    82 // Allow explicit quoted stream I/O.
    83 static inline auto quoted(const std::string& s)
    84 {
    85-    return boost::io::quoted(s, '&');
    86+    return std::quoted(s, '&');
    


    hebasto commented at 3:17 pm on October 18, 2021:

    6316193878d66bb35dbf96f8ec2047591e3bdb46 “refactor: replace boost::filesystem with std::filesystem”

    boost::io::quoted and std::quoted differ in the parameter order, therefore,

    0    return std::quoted(s, '"', '&');
    

    Also see #20744 (review)


    fanquake commented at 4:12 am on October 21, 2021:
    Fixed in next push.
  191. hebasto commented at 6:27 pm on October 18, 2021: member

    I was able to cross compile for Windows with the two following steps:

    1. static cast fs::path instances to std::filesystem::path for all of stream objects
      0diff --git a/src/init.cpp b/src/init.cpp
      1index 164b7bb55..2cbef67ea 100644
      2--- a/src/init.cpp
      3+++ b/src/init.cpp
      4@@ -118,7 +118,7 @@ static fs::path GetPidFile(const ArgsManager& args)
      5 
      6 [[nodiscard]] static bool CreatePidFile(const ArgsManager& args)
      7 {
      8-    fsbridge::ofstream file{GetPidFile(args)};
      9+    fsbridge::ofstream file{static_cast<std::filesystem::path>(GetPidFile(args))};
     10     if (file) {
     11 #ifdef WIN32
     12         tfm::format(file, "%d\n", GetCurrentProcessId());
     13diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
     14index 4262866f3..9a810e0b8 100644
     15--- a/src/qt/guiutil.cpp
     16+++ b/src/qt/guiutil.cpp
     17@@ -425,7 +425,7 @@ bool openBitcoinConf()
     18     fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
     19 
     20     /* Create the file */
     21-    fsbridge::ofstream configFile(pathConfig, std::ios_base::app);
     22+    fsbridge::ofstream configFile(static_cast<std::filesystem::path>(pathConfig), std::ios_base::app);
     23 
     24     if (!configFile.good())
     25         return false;
     26diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
     27index 3245e04cd..426d10cb3 100644
     28--- a/src/rpc/request.cpp
     29+++ b/src/rpc/request.cpp
     30@@ -85,7 +85,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
     31      */
     32     fsbridge::ofstream file;
     33     fs::path filepath_tmp = GetAuthCookieFile(true);
     34-    file.open(filepath_tmp);
     35+    file.open(static_cast<std::filesystem::path>(filepath_tmp));
     36     if (!file.is_open()) {
     37         LogPrintf("Unable to open cookie authentication file %s for writing\n", fs::PathToString(filepath_tmp));
     38         return false;
     39@@ -110,7 +110,7 @@ bool GetAuthCookie(std::string *cookie_out)
     40     fsbridge::ifstream file;
     41     std::string cookie;
     42     fs::path filepath = GetAuthCookieFile();
     43-    file.open(filepath);
     44+    file.open(static_cast<std::filesystem::path>(filepath));
     45     if (!file.is_open())
     46         return false;
     47     std::getline(file, cookie);
     48diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
     49index ecb838a7d..9a7794ad7 100644
     50--- a/src/test/fs_tests.cpp
     51+++ b/src/test/fs_tests.cpp
     52@@ -45,37 +45,37 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
     53     fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃";
     54     fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃";
     55     {
     56-        fsbridge::ofstream file(tmpfile1);
     57+        fsbridge::ofstream file(static_cast<std::filesystem::path>(tmpfile1));
     58         file << "bitcoin";
     59     }
     60     {
     61-        fsbridge::ifstream file(tmpfile2);
     62+        fsbridge::ifstream file(static_cast<std::filesystem::path>(tmpfile2));
     63         std::string input_buffer;
     64         file >> input_buffer;
     65         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     66     }
     67     {
     68-        fsbridge::ifstream file(tmpfile1, std::ios_base::in | std::ios_base::ate);
     69+        fsbridge::ifstream file(static_cast<std::filesystem::path>(tmpfile1), std::ios_base::in | std::ios_base::ate);
     70         std::string input_buffer;
     71         file >> input_buffer;
     72         BOOST_CHECK_EQUAL(input_buffer, "");
     73     }
     74     {
     75-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::app);
     76+        fsbridge::ofstream file(static_cast<std::filesystem::path>(tmpfile2), std::ios_base::out | std::ios_base::app);
     77         file << "tests";
     78     }
     79     {
     80-        fsbridge::ifstream file(tmpfile1);
     81+        fsbridge::ifstream file(static_cast<std::filesystem::path>(tmpfile1));
     82         std::string input_buffer;
     83         file >> input_buffer;
     84         BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
     85     }
     86     {
     87-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::trunc);
     88+        fsbridge::ofstream file(static_cast<std::filesystem::path>(tmpfile2), std::ios_base::out | std::ios_base::trunc);
     89         file << "bitcoin";
     90     }
     91     {
     92-        fsbridge::ifstream file(tmpfile1);
     93+        fsbridge::ifstream file(static_cast<std::filesystem::path>(tmpfile1));
     94         std::string input_buffer;
     95         file >> input_buffer;
     96         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     97diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
     98index 15cba9e3e..b8f1b1389 100644
     99--- a/src/test/settings_tests.cpp
    100+++ b/src/test/settings_tests.cpp
    101@@ -37,7 +37,7 @@ inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, u
    102 inline void WriteText(const fs::path& path, const std::string& text)
    103 {
    104     fsbridge::ofstream file;
    105-    file.open(path);
    106+    file.open(static_cast<std::filesystem::path>(path));
    107     file << text;
    108 }
    109 
    110diff --git a/src/util/settings.cpp b/src/util/settings.cpp
    111index 7fb35c073..608823841 100644
    112--- a/src/util/settings.cpp
    113+++ b/src/util/settings.cpp
    114@@ -4,6 +4,7 @@
    115 
    116 #include <util/settings.h>
    117 
    118+#include <fs.h>
    119 #include <tinyformat.h>
    120 #include <univalue.h>
    121 
    122@@ -64,7 +65,7 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
    123     if (!fs::exists(path)) return true;
    124 
    125     fsbridge::ifstream file;
    126-    file.open(path);
    127+    file.open(static_cast<std::filesystem::path>(path));
    128     if (!file.is_open()) {
    129       errors.emplace_back(strprintf("%s. Please check permissions.", fs::PathToString(path)));
    130       return false;
    131@@ -107,7 +108,7 @@ bool WriteSettings(const fs::path& path,
    132         out.__pushKV(value.first, value.second);
    133     }
    134     fsbridge::ofstream file;
    135-    file.open(path);
    136+    file.open(static_cast<std::filesystem::path>(path));
    137     if (file.fail()) {
    138         errors.emplace_back(strprintf("Error: Unable to open settings file %s for writing", fs::PathToString(path)));
    139         return false;
    140diff --git a/src/util/system.cpp b/src/util/system.cpp
    141index 0ed03ae4a..425bdef5c 100644
    142--- a/src/util/system.cpp
    143+++ b/src/util/system.cpp
    144@@ -888,7 +888,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    145     }
    146 
    147     const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
    148-    fsbridge::ifstream stream(GetConfigFile(confPath));
    149+    fsbridge::ifstream stream(static_cast<std::filesystem::path>(GetConfigFile(confPath)));
    150 
    151     // not ok to have a config file specified that cannot be opened
    152     if (IsArgSet("-conf") && !stream.good()) {
    153@@ -935,7 +935,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    154             const size_t default_includes = add_includes({});
    155 
    156             for (const std::string& conf_file_name : conf_file_names) {
    157-                fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name));
    158+                fsbridge::ifstream conf_file_stream(static_cast<std::filesystem::path>(GetConfigFile(conf_file_name)));
    159                 if (conf_file_stream.good()) {
    160                     if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
    161                         return false;
    162diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
    163index f1034c267..484746edb 100644
    164--- a/src/wallet/db.cpp
    165+++ b/src/wallet/db.cpp
    166@@ -88,7 +88,7 @@ bool IsBDBFile(const fs::path& path)
    167     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    168     if (size < 4096) return false;
    169 
    170-    fsbridge::ifstream file(path, std::ios::binary);
    171+    fsbridge::ifstream file(static_cast<std::filesystem::path>(path), std::ios::binary);
    172     if (!file.is_open()) return false;
    173 
    174     file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
    175@@ -112,7 +112,7 @@ bool IsSQLiteFile(const fs::path& path)
    176     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    177     if (size < 512) return false;
    178 
    179-    fsbridge::ifstream file(path, std::ios::binary);
    180+    fsbridge::ifstream file(static_cast<std::filesystem::path>(path), std::ios::binary);
    181     if (!file.is_open()) return false;
    182 
    183     // Magic is at beginning and is 16 bytes long
    184diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
    185index 08d94b76d..5b1fa8933 100644
    186--- a/src/wallet/dump.cpp
    187+++ b/src/wallet/dump.cpp
    188@@ -4,6 +4,7 @@
    189 
    190 #include <wallet/dump.h>
    191 
    192+#include <fs.h>
    193 #include <util/translation.h>
    194 #include <wallet/wallet.h>
    195 
    196@@ -26,7 +27,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
    197         return false;
    198     }
    199     fsbridge::ofstream dump_file;
    200-    dump_file.open(path);
    201+    dump_file.open(static_cast<std::filesystem::path>(path));
    202     if (dump_file.fail()) {
    203         error = strprintf(_("Unable to open %s for writing"), fs::PathToString(path));
    204         return false;
    205@@ -120,7 +121,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
    206         error = strprintf(_("Dump file %s does not exist."), fs::PathToString(dump_path));
    207         return false;
    208     }
    209-    fsbridge::ifstream dump_file(dump_path);
    210+    fsbridge::ifstream dump_file(static_cast<std::filesystem::path>(dump_path));
    211 
    212     // Compute the checksum
    213     CHashWriter hasher(0, 0);
    214diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
    215index 9b09bc23d..c5ae321b7 100644
    216--- a/src/wallet/rpcdump.cpp
    217+++ b/src/wallet/rpcdump.cpp
    218@@ -5,6 +5,7 @@
    219 #include <chain.h>
    220 #include <clientversion.h>
    221 #include <core_io.h>
    222+#include <fs.h>
    223 #include <interfaces/chain.h>
    224 #include <key_io.h>
    225 #include <merkleblock.h>
    226@@ -758,7 +759,7 @@ RPCHelpMan dumpwallet()
    227     }
    228 
    229     fsbridge::ofstream file;
    230-    file.open(filepath);
    231+    file.open(static_cast<std::filesystem::path>(filepath));
    232     if (!file.is_open())
    233         throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
    234 
    235diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
    236index e031f38b2..c73340c53 100644
    237--- a/src/wallet/test/db_tests.cpp
    238+++ b/src/wallet/test/db_tests.cpp
    239@@ -25,7 +25,7 @@ BOOST_AUTO_TEST_CASE(getwalletenv_file)
    240     std::string test_name = "test_name.dat";
    241     const fs::path datadir = gArgs.GetDataDirNet();
    242     fs::path file_path = datadir / test_name;
    243-    std::ofstream f(file_path);
    244+    std::ofstream f(static_cast<std::filesystem::path>(file_path));
    245     f.close();
    246 
    247     std::string filename;
    248diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
    249index 0755af42a..6dbdd8c07 100644
    250--- a/src/wallet/test/init_test_fixture.cpp
    251+++ b/src/wallet/test/init_test_fixture.cpp
    252@@ -32,7 +32,7 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
    253     fs::create_directories(m_walletdir_path_cases["default"]);
    254     fs::create_directories(m_walletdir_path_cases["custom"]);
    255     fs::create_directories(m_walletdir_path_cases["relative"]);
    256-    std::ofstream f(m_walletdir_path_cases["file"]);
    257+    std::ofstream f(static_cast<std::filesystem::path>(m_walletdir_path_cases["file"]));
    258     f.close();
    259 }
    260 
    
    1. configure with --disable-external-signer, because boost/process.hpp depends on boost::filesystem

    UPDATE: The following code: https://github.com/bitcoin/bitcoin/blob/ff65b696f3c6f6e17a790c6646249163ddb39eda/src/util/system.cpp#L1266-L1271 induces a linker error:

    0/usr/bin/x86_64-w64-mingw32-ld: libbitcoin_util.a(libbitcoin_util_a-system.o):system.cpp:(.text$_ZN5boost7process6detail18basic_execute_implIcJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS1_7windows8pipe_outILi1ELin1EEENSC_ILi2ELin1EEENSB_7pipe_inEEEENS0_5childEDpOT0_[_ZN5boost7process6detail18basic_execute_implIcJRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS1_7windows8pipe_outILi1ELin1EEENSC_ILi2ELin1EEENSB_7pipe_inEEEENS0_5childEDpOT0_]+0x362): undefined reference to `boost::filesystem::path::operator/=(boost::filesystem::path const&)'
    
  192. in src/wallet/db.cpp:32 in 6316193878 outdated
    28@@ -29,15 +29,14 @@ std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
    29 
    30         try {
    31             // Get wallet path relative to walletdir by removing walletdir from the wallet path.
    32-            // This can be replaced by boost::filesystem::lexically_relative once boost is bumped to 1.60.
    


    ryanofsky commented at 10:14 pm on October 18, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    This suggestion is still relevant. It would be better to implement or update it than to drop it. It can be implemented with:

     0@@ -12,7 +12,6 @@
     1 
     2 std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
     3 {
     4-    const size_t offset = wallet_dir.native().size() + (wallet_dir == wallet_dir.root_name() ? 0 : 1);
     5     std::vector<fs::path> paths;
     6     std::error_code ec;
     7 
     8@@ -29,8 +28,7 @@ std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
     9 
    10         try {
    11             // Get wallet path relative to walletdir by removing walletdir from the wallet path.
    12-            const auto path_str = it->path().native().substr(offset);
    13-            const fs::path path{path_str.begin(), path_str.end()};
    14+            const fs::path path = it->path().lexically_relative(wallet_dir);
    15 
    16             if (it->status().type() == fs::file_type::directory &&
    17                 (IsBDBFile(BDBDataFile(it->path())) || IsSQLiteFile(SQLiteDataFile(it->path())))) {
    

    fanquake commented at 4:13 am on October 21, 2021:
    Taken.
  193. in src/wallet/test/init_test_fixture.cpp:30 in 6316193878 outdated
    28+    m_walletdir_path_cases["trailing"] = m_datadir / ("wallets" + sep);
    29+    m_walletdir_path_cases["trailing2"] = m_datadir / ("wallets" + sep + sep);
    30 
    31     fs::current_path(m_datadir);
    32-    m_walletdir_path_cases["relative"] = "wallets";
    33+    m_walletdir_path_cases["relative"] = fs::path("wallets");
    


    ryanofsky commented at 10:17 pm on October 18, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    It’s fine to make a path from an ASCII string literal, so this could be left unchanged:

     0diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
     1index 0755af42a10..f9fb17080b4 100644
     2--- a/src/wallet/test/init_test_fixture.cpp
     3+++ b/src/wallet/test/init_test_fixture.cpp
     4@@ -27,7 +27,7 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
     5     m_walletdir_path_cases["trailing2"] = m_datadir / ("wallets" + sep + sep);
     6 
     7     fs::current_path(m_datadir);
     8-    m_walletdir_path_cases["relative"] = fs::path("wallets");
     9+    m_walletdir_path_cases["relative"] = "wallets";
    10 
    11     fs::create_directories(m_walletdir_path_cases["default"]);
    12     fs::create_directories(m_walletdir_path_cases["custom"]);
    
  194. ryanofsky commented at 10:22 pm on October 18, 2021: member
    Suggested some simplifications below. (These were previously part of the branch I posted earlier #20744 (comment))
  195. in src/util/system.cpp:405 in 6316193878 outdated
    401@@ -414,7 +402,7 @@ const fs::path& ArgsManager::GetBlocksDirPath() const
    402     path /= fs::PathFromString(BaseParams().DataDir());
    403     path /= "blocks";
    404     fs::create_directories(path);
    405-    path = StripRedundantLastElementsOfPath(path);
    406+    path = fs::canonical(path);
    


    ryanofsky commented at 10:42 pm on October 18, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    I think this line should just be deleted. It looks like this StripRedundantLastElementsOfPath call was added by mistake in #21244, and never did anything, because the last path element above is always “blocks”. Keeping this just adds unnecessary complexity and creates a minor change behavior (it resolves symlinks now)


    MarcoFalke commented at 8:40 am on October 19, 2021:
    This was added in #20080 , not 21244

    hebasto commented at 10:02 am on October 19, 2021:

    it resolves symlinks now

    Isn’t it a better user experience? At least for -blocksdir?


    MarcoFalke commented at 10:05 am on October 19, 2021:
    new features should be added in non-refactoring commits

    ryanofsky commented at 12:27 pm on October 19, 2021:

    re: #20744 (review)

    Isn’t it a better user experience? At least for -blocksdir?

    This is a minor point, but I don’t think changing the path in general is a better experience, and I’m not sure in which cases it could be a better experience. If I specify -blocksdir=/var/lib/bitcoin/blocks I think like to see that same path when I’m grepping through log files, or checking the result of some RPC, not some different transformed path if the system happens to be using symlinks to manage storage.

    Either way, I think dropping this line to preserve behavior makes sense for this commit. Marco was right this StripRedundantLastElementsOfPath call was was added in #20080, and in even in that PR it should not have any effect because the last path element was "blocks" not ".":

    0path /= "blocks";
    1...
    2path = StripRedundantLastElementsOfPath(path);
    

    hebasto commented at 3:04 pm on October 19, 2021:

    Agree with @ryanofsky in both:

    dropping this line to preserve behavior makes sense for this commit

    even in that PR it should not have any effect


    fanquake commented at 4:14 am on October 21, 2021:
    I’ve dropped this line for now.
  196. in src/util/system.cpp:243 in 6316193878 outdated
    238@@ -238,19 +239,6 @@ static bool CheckValid(const std::string& key, const util::SettingsValue& val, u
    239     return true;
    240 }
    241 
    242-namespace {
    243-fs::path StripRedundantLastElementsOfPath(const fs::path& path)
    


    ryanofsky commented at 12:59 pm on October 19, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    To preserve behavior, I think it’d be best to keep this function instead of replacing it with a call to canonical which adds new transformations like normalizing path elements in the middle of the path and resolving symlinks. Just a small tweak here is required to port from boost:

     0diff --git a/src/util/system.cpp b/src/util/system.cpp
     1index 0e516f10949..99688de0483 100644
     2--- a/src/util/system.cpp
     3+++ b/src/util/system.cpp
     4@@ -243,7 +243,7 @@ namespace {
     5 fs::path StripRedundantLastElementsOfPath(const fs::path& path)
     6 {
     7     auto result = path;
     8-    while (fs::PathToString(result.filename()) == ".") {
     9+    while (result.filename().empty() || fs::PathToString(result.filename()) == ".") {
    10         result = result.parent_path();
    11     }
    12 
    

    fanquake commented at 4:14 am on October 21, 2021:
    We’re now preserving StripRedundantLastElementsOfPath and I’ve included this change.
  197. in src/util/system.cpp:436 in 6316193878 outdated
    432@@ -445,7 +433,7 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const
    433         fs::create_directories(path / "wallets");
    434     }
    435 
    436-    path = StripRedundantLastElementsOfPath(path);
    437+    path = fs::canonical(path);
    


    ryanofsky commented at 1:01 pm on October 19, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    Mentioned above, but I think it’d be best to keep this line unchanged to preserve behavior, keeping the call to StripRedundantLastElementsOfPath instead of switching to canonical


    fanquake commented at 4:15 am on October 21, 2021:
    Reverted the change here.
  198. in src/wallet/test/init_test_fixture.cpp:31 in 6316193878 outdated
    22@@ -23,16 +23,16 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
    23     m_walletdir_path_cases["custom"] = m_datadir / "my_wallets";
    24     m_walletdir_path_cases["nonexistent"] = m_datadir / "path_does_not_exist";
    25     m_walletdir_path_cases["file"] = m_datadir / "not_a_directory.dat";
    26-    m_walletdir_path_cases["trailing"] = m_datadir / "wallets" / sep;
    27-    m_walletdir_path_cases["trailing2"] = m_datadir / "wallets" / sep / sep;
    28+    m_walletdir_path_cases["trailing"] = m_datadir / ("wallets" + sep);
    29+    m_walletdir_path_cases["trailing2"] = m_datadir / ("wallets" + sep + sep);
    


    ryanofsky commented at 1:46 pm on October 19, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (6316193878d66bb35dbf96f8ec2047591e3bdb46)

    Note just to explain this change:

    • In boost, path("wallets") / path("/") results in path("wallets/"), because the two paths are just literally concatenated with an extra separator if needed. https://www.boost.org/doc/libs/1_68_0/libs/filesystem/doc/reference.html#path-appends.
    • In c++17, path("wallets") / path("/") results in path("/") more similar to a python-style path join because the second path is an absolute path so it just becomes the new path.
    • Without these changes the two trailing tests try to use the root directory / as the wallets directory and fail.
    • Changing / to + makes the tests work the same as prevously
  199. ryanofsky commented at 2:10 pm on October 19, 2021: member
    Finally finished going through commit 6316193878d66bb35dbf96f8ec2047591e3bdb46 (in branch e4d50b8f0367e9ac3bb6189c9299cdda9c9d7c7e) and I think it will look good with all the suggested changes. After these changes, I’m still not sure if would be 100% refactoring because of possible system_complete and absolute differences mentioned in the commit description about extra slashes, but the the only place these could possibly be show up is in the middle regtest/testnet GetDataDir paths, so they would be harmless and the commit message already mentions this. And aside from that there are no other places I would see behavior changing at all.
  200. fanquake force-pushed on Oct 21, 2021
  201. fanquake commented at 8:00 am on October 21, 2021: member

    Forgot to push?

    Was working on the Guix changes. I’ve now cherry-picked patches from GCC 9, which should mirror what Debian did with it’s mingw-w64 and GCC 8, such that the Guix Windows cross compile should work when using std::filesystem. Compiling GCC 8.4.0 (with --enable-libstdcxx-filesystem-ts=yes) and mingw-w64 works, however I’m running into issues when compiling Core, and will investigate further. Note that this branch currently cross-compiles for Windows using mingw-w64 outside of Guix. I’ve pushed up the current changes in any case.

    Current Guix issue when cross-compiling for Windows:

     0  CXX      libbitcoin_server_a-net_processing.o
     1  CXX      libbitcoin_server_a-noui.o
     2  CXX      libbitcoin_server_a-pow.o
     3In file included from ./fs.h:12,
     4                 from ./addrdb.h:9,
     5                 from ./banman.h:8,
     6                 from init.cpp:13:
     7/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream: In instantiation of 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode) [with _Path = std::filesystem::__cxx11::path; _Require = std::filesystem::__cxx11::path; _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]':
     8init.cpp:121:81:   required from here
     9/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:839:38: error: no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(const value_type*, std::ios_base::openmode&)'
    10  : basic_ofstream(__s.c_str(), __mode)
    11                                      ^
    12/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:845:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(std::basic_ofstream<_CharT, _Traits>&&) [with _CharT = char; _Traits = std::char_traits<char>]'
    13       basic_ofstream(basic_ofstream&& __rhs)
    14       ^~~~~~~~~~~~~~
    15/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:845:7: note:   candidate expects 1 argument, 2 provided
    16/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:837:2: note: candidate: 'template<class _Path, class _Require> std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode)'
    17  basic_ofstream(const _Path& __s,
    18  ^~~~~~~~~~~~~~
    19/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:837:2: note:   template argument deduction/substitution failed:
    20/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:836:32: error: request for member 'make_preferred' in 'std::declval<const wchar_t*&>()', which is of non-class type 'const wchar_t*'
    21       template<typename _Path, typename _Require = _If_fs_path<_Path>>
    22                                ^~~~~~~~
    23/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:820:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::__cxx11::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::_Ios_Openmode]'
    24       basic_ofstream(const std::string& __s,
    25       ^~~~~~~~~~~~~~
    26/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:820:7: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
    27/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:785:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]'
    28       basic_ofstream(const char* __s,
    29       ^~~~~~~~~~~~~~
    30/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:785:7: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const char*'
    31/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:774:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char; _Traits = std::char_traits<char>]'
    32       basic_ofstream(): __ostream_type(), _M_filebuf()
    33       ^~~~~~~~~~~~~~
    34/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:774:7: note:   candidate expects 0 arguments, 2 provided
    35/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:839:38: error: no matching function for call to 'std::basic_ofstream<char>::basic_ofstream(const value_type*, std::ios_base::openmode&)'
    36  : basic_ofstream(__s.c_str(), __mode)
    37                                      ^
    38/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:845:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(std::basic_ofstream<_CharT, _Traits>&&) [with _CharT = char; _Traits = std::char_traits<char>]'
    39       basic_ofstream(basic_ofstream&& __rhs)
    40       ^~~~~~~~~~~~~~
    41/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:845:7: note:   candidate expects 1 argument, 2 provided
    42/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:837:2: note: candidate: 'template<class _Path, class _Require> std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const _Path&, std::ios_base::openmode)'
    43  basic_ofstream(const _Path& __s,
    44  ^~~~~~~~~~~~~~
    45/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:837:2: note:   template argument deduction/substitution failed:
    46/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:836:32: error: request for member 'make_preferred' in 'std::declval<const wchar_t*&>()', which is of non-class type 'const wchar_t*'
    47       template<typename _Path, typename _Require = _If_fs_path<_Path>>
    48                                ^~~~~~~~
    49/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:820:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const string&, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::__cxx11::string = std::__cxx11::basic_string<char>; std::ios_base::openmode = std::_Ios_Openmode]'
    50       basic_ofstream(const std::string& __s,
    51       ^~~~~~~~~~~~~~
    52/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:820:7: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const string&' {aka 'const std::__cxx11::basic_string<char>&'}
    53/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:785:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]'
    54       basic_ofstream(const char* __s,
    55       ^~~~~~~~~~~~~~
    56/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:785:7: note:   no known conversion for argument 1 from 'const value_type*' {aka 'const wchar_t*'} to 'const char*'
    57/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:774:7: note: candidate: 'std::basic_ofstream<_CharT, _Traits>::basic_ofstream() [with _CharT = char; _Traits = std::char_traits<char>]'
    58       basic_ofstream(): __ostream_type(), _M_filebuf()
    59       ^~~~~~~~~~~~~~
    60/gnu/store/pjmb3jry271q98pfrdr44sx4w0cy6mw5-gcc-cross-x86_64-w64-mingw32-8.4.0/include/c++/fstream:774:7: note:   candidate expects 0 arguments, 2 provided
    61  CXX      libbitcoin_server_a-rest.o
    62  CXX      libbitcoin_server_a-shutdown.o
    63  CXX      libbitcoin_server_a-signet.o
    64make[2]: *** [Makefile:9217: libbitcoin_server_a-init.o] Error 1
    
  202. hebasto commented at 9:26 am on October 21, 2021: member

    @MarcoFalke

    https://cirrus-ci.com/task/6003193059475456:

    0ERROR: The syscall "sendfile" (syscall number 40) is not allowed by the syscall sandbox in thread "httpworker.2". Please report.
    
  203. fanquake commented at 9:28 am on October 21, 2021: member

    https://cirrus-ci.com/task/6003193059475456:

    0 node1 2021-10-21T08:30:38.456944Z [httpworker.0] [wallet/wallet.h:792] [WalletLogPrintf] [default wallet] Rescan completed in               0ms 
    1 node1 2021-10-21T08:30:38.458646Z [http] [httpserver.cpp:238] [http_request_cb] Received a POST request for / from 127.0.0.1:57124 
    2 node1 2021-10-21T08:30:38.458768Z [httpworker.2] [rpc/request.cpp:174] [parse] ThreadRPCServer method=backupwallet user=__cookie__ 
    3 node1 2021-10-21T08:30:38.460693Z [httpworker.2] [util/syscall_sandbox.cpp:487] [SyscallSandboxDebugSignalHandler] ERROR: The syscall "sendfile" (syscall number 40) is not allowed by the syscall sandbox in thread "httpworker.2". Please report. 
    

    Yes it’s happening during filesystem operations. I’ll add an exception to the commit where we swap to std::filesystem.

  204. MarcoFalke commented at 10:30 am on October 21, 2021: member
    Any idea why the windows unit test failed?
  205. fanquake commented at 10:32 am on October 21, 2021: member

    Any idea why the windows unit test failed?

    0test/util_tests.cpp(50): Entering test case "util_datadir"
    12021-10-21T09:51:37.572779Z [test/util/setup_common.cpp:65] [Seed] Seed: Setting random seed for current tests to RANDOM_CTX_SEED=72b0882141d4b40dac04b3bff3080a44a6998b9418d1227d677d5e2ab298171c
    22021-10-21T09:51:37.572779Z [init/common.cpp:165] [LogPackageVersion] Bitcoin Core version v22.99.0-ef048d3a36c4 (release build)
    32021-10-21T09:51:37.572779Z [init.cpp:904] [AppInitParameterInteraction] Assuming ancestors of block 00000000000000000008a89e854d57e5667df88f1cdef6fde2fbca1de5b639ad have valid signatures.
    42021-10-21T09:51:37.572779Z [init.cpp:917] [AppInitParameterInteraction] Setting nMinimumChainWork=00000000000000000000000000000000000000001fa4663bbbe19f82de910280
    52021-10-21T09:51:37.573779Z [script/sigcache.cpp:101] [InitSignatureCache] Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
    62021-10-21T09:51:37.574779Z [validation.cpp:1274] [InitScriptExecutionCache] Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
    7test/util_tests.cpp(72): error: in "util_tests/util_datadir": check dd_norm == args.GetDataDirBase() has failed ["C:\\users\\root\\Temp\\test_common_Bitcoin Core\\04ef3851bd5ebef826abb443ef652d2eee95c19cbcefc481267df04b8f0df460" != ""]
    8test/util_tests.cpp(50): Leaving test case "util_datadir"; testing time: 57090us
    
  206. hebasto commented at 10:35 am on October 21, 2021: member

    Any idea why the windows unit test failed?

    Testing a fix – https://github.com/hebasto/bitcoin/commit/b87da976f8b1faa502b26db9052b505e9ebcb955

    UPDATE: not working (

  207. hebasto commented at 10:39 am on October 21, 2021: member

    There is an inconsistency in the current state of this PR: fsbridge::ifstream is used along with std::ifstream (same for ofstream).

    Shouldn’t we stick to the only namespace – fsbridge or std?

  208. hebasto commented at 11:13 am on October 21, 2021: member

    Was working on the Guix changes. I’ve now cherry-picked patches from GCC 9

    Does switching to GCC 9 in the Guix building system look more preferable?

  209. in src/init.cpp:121 in b70c84348a outdated
    117@@ -118,7 +118,7 @@ static fs::path GetPidFile(const ArgsManager& args)
    118 
    119 [[nodiscard]] static bool CreatePidFile(const ArgsManager& args)
    120 {
    121-    fsbridge::ofstream file{GetPidFile(args)};
    122+    fsbridge::ofstream file{static_cast<std::filesystem::path>(GetPidFile(args))};
    


    ryanofsky commented at 12:44 pm on October 21, 2021:

    In commit “refactor: replace boost::filesystem with std::filesystem” (b70c84348ac7a8e427a1183f894c73e52c734529)

    These static_casts seem to be added because even though GetPidFile returns fs::path and fs::path inherits from std::filesystem::path, the basic_ofstream constructor has an _If_fs_path requirement that needs an exact std::filesystem::path match:

    0      template<typename _Path, typename _Require = _If_fs_path<_Path>>
    1        basic_ofstream(const _Path& __s,
    2                       ios_base::openmode __mode = ios_base::out)
    3        : basic_ofstream(__s.c_str(), __mode)
    4        { }
    

    It might be nice to drop the need for these static_casts in fsbridge with something like

    0-    typedef std::ofstream ofstream;
    1+    class ofstream : public std::ofstream
    2+    {
    3+        using std::ofstream::ofstream;
    4+        ofstream(const fs::path& p) : ofstream(static_cast<const std::filesystem::path&>(p)) {}
    5+    };
    

    Another alternative would just be to pass path.c_str() instead of path when constructing ofstream objects. This should be safe because c_str returns a wide string on windows.


    hebasto commented at 1:35 pm on October 21, 2021:
    I’d prefer to use path.c_str() that will allow us to use just std::ifstream and std::ofstream.

    ryanofsky commented at 4:49 pm on November 1, 2021:

    re: #20744 (review)

    I was looking into this again, thinking passing path.native() might be a third alternative, but it doesn’t work because there’s no constructor https://en.cppreference.com/w/cpp/io/basic_ifstream/basic_ifstream accepting the wstring on windows like the one accepting the wide character pointer returned by path.c_str().

  210. ryanofsky commented at 1:15 pm on October 21, 2021: member

    Reviewing b70c84348ac7a8e427a1183f894c73e52c734529 (in branch f53be20eade794e55470473f03a8d05d57691c87)


    re: #20744 (comment)

    Any idea why the windows unit test failed?

    0test/util_tests.cpp(72): error: in "util_tests/util_datadir": check dd_norm == args.GetDataDirBase() has failed ["C:\\users\\root\\Temp\\test_common_Bitcoin Core\\04ef3851bd5ebef826abb443ef652d2eee95c19cbcefc481267df04b8f0df460" != ""]
    

    The test that’s failing is:

    0    args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
    1    args.ClearPathCache();
    2    BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
    

    because args.GetDataDirBase() is returning "", because windows does not consider "dir/.//" to be a valid directory, so path = "" in GetDataDir is hit:

    0    std::string datadir = GetArg("-datadir", "");
    1    if (!datadir.empty()) {
    2        path = fs::absolute(fs::PathFromString(datadir));
    3        if (!fs::is_directory(path)) {
    4            path = "";
    5            return path;
    6        }
    

    Possible fix 1:

     0diff --git a/src/util/system.cpp b/src/util/system.cpp
     1index 03af96dc3cf..0e026a35347 100644
     2--- a/src/util/system.cpp
     3+++ b/src/util/system.cpp
     4@@ -429,7 +429,7 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const
     5 
     6     std::string datadir = GetArg("-datadir", "");
     7     if (!datadir.empty()) {
     8-        path = fs::absolute(fs::PathFromString(datadir));
     9+        path = fs::absolute(StripRedundantLastElementsOfPath(fs::PathFromString(datadir)));
    10         if (!fs::is_directory(path)) {
    11             path = "";
    12             return path;
    

    Possible fix 2:

     0diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
     1index b1300d06ba6..f6e2e7907fb 100644
     2--- a/src/test/util_tests.cpp
     3+++ b/src/test/util_tests.cpp
     4@@ -69,7 +69,12 @@ BOOST_AUTO_TEST_CASE(util_datadir)
     5 
     6     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
     7     args.ClearPathCache();
     8+#ifndef WIN32
     9     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
    10+#else
    11+    // Windows does not consider "datadir/.//" to be a valid directory path.
    12+    BOOST_CHECK(args.GetDataDirBase().empty());
    13+#endif
    14
    15---
    

    re: #20744 (comment)

    Shouldn’t we stick to the only namespace – fsbridge or std?

    I’d assume we should probably either use fsbridge in all application code, or else should drop it entirely.

  211. in build_msvc/vcpkg.json:6 in f53be20ead outdated
    2@@ -3,7 +3,6 @@
    3   "version-string": "1",
    4   "dependencies": [
    5     "berkeleydb",
    6-    "boost-filesystem",
    


    hebasto commented at 8:40 pm on October 21, 2021:

    Despite of removing boost-filesystem from the vcpkg manifest, the “Win64 native” CI task does build it:

    0...
    1  The following packages will be built and installed:
    2...
    3      boost-filesystem[core]:x64-windows-static -> 1.75.0#1
    4...
    

    I assume it is caused by dependencies of the boost-process package.


    fanquake commented at 10:54 am on December 14, 2021:
    Going to resolve this as I don’t think there’s anything we can do here. Even if it is still being built, we aren’t using it.
  212. fanquake referenced this in commit 7efc628539 on Oct 30, 2021
  213. DrahtBot added the label Needs rebase on Oct 30, 2021
  214. sidhujag referenced this in commit 7704bb722b on Oct 30, 2021
  215. PastaPastaPasta referenced this in commit 60b7b932e2 on Nov 1, 2021
  216. PastaPastaPasta referenced this in commit 0627ea1d4c on Nov 1, 2021
  217. PastaPastaPasta referenced this in commit 2d30d33811 on Nov 3, 2021
  218. fanquake commented at 7:43 am on November 10, 2021: member

    Does switching to GCC 9 in the Guix building system look more preferable?

    I’d rather we switch to GCC 10. I’m currently upstreaming some changes, i.e https://lists.gnu.org/archive/html/guix-patches/2021-11/msg00346.html, to fixup the GCC 10 build in Guix, and will open a separate PR proposing that change.

  219. janus referenced this in commit a9092f47aa on Nov 11, 2021
  220. pravblockc referenced this in commit 2da267b8c3 on Nov 18, 2021
  221. fanquake referenced this in commit 681b25e3cd on Nov 25, 2021
  222. sidhujag referenced this in commit 67658eec7d on Nov 25, 2021
  223. fanquake force-pushed on Dec 23, 2021
  224. fanquake commented at 5:04 am on December 23, 2021: member
    I’ve rebased this on master and #23778 (dropping 9604eda1abe6ffc02c97e3434c3c2c4ce1250794 which was the “backport std::filesystem to GCC” commit). I’ve also addressed a number of the comments, including sticking to using fsbridge and removing the use of the static_casts in favour of passing path.c_str(), as well as included some suggestions to fix test failures. There are still a couple failures in the Windows unit tests that need to be addressed.
  225. DrahtBot removed the label Needs rebase on Dec 23, 2021
  226. fanquake force-pushed on Dec 23, 2021
  227. fanquake commented at 9:48 am on December 23, 2021: member

    Addressed:

    The syscall “sendfile” (syscall number 40) is not allowed by the syscall sandbox in thread “httpworker.0”.

  228. fanquake force-pushed on Dec 23, 2021
  229. fanquake referenced this in commit bb0c4978db on Dec 24, 2021
  230. fanquake referenced this in commit 6bd020e2f4 on Dec 24, 2021
  231. fanquake referenced this in commit 2da5bc557d on Dec 24, 2021
  232. fanquake referenced this in commit 5668ad4339 on Dec 24, 2021
  233. fanquake referenced this in commit 711ce2e533 on Jan 7, 2022
  234. fanquake force-pushed on Jan 7, 2022
  235. sidhujag referenced this in commit 870a4d39b0 on Jan 7, 2022
  236. in src/rpc/request.cpp:88 in f51b6341ac outdated
    84@@ -85,7 +85,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
    85      */
    86     fsbridge::ofstream file;
    87     fs::path filepath_tmp = GetAuthCookieFile(true);
    88-    file.open(filepath_tmp);
    89+    file.open(filepath_tmp.c_str());
    


    martinus commented at 5:33 pm on January 7, 2022:

    Is the c_str() actually needed? On my system (g++ 11.1) this also compiles when I write file.open(filepath_tmp);. This calls operator string_type() const { return _M_pathname; } from std::fileystem::path.

    Or maybe add operator string_type() const = delete; to explicitly delete that conversion in the path wrapper


    ryanofsky commented at 6:05 pm on January 7, 2022:
    c_str is needed on some platform (mingw, IIRC) because of an _If_fs_path requirement there which requires std::filesystem::path class argument or a string argument, and won’t accept a std::filesystem::path subclass like fs::path (https://github.com/bitcoin/bitcoin/pull/20744#discussion_r733637362, #20744 (comment))

    martinus commented at 6:10 pm on January 7, 2022:
    Thanks!

    MarcoFalke commented at 3:47 pm on January 25, 2022:
    Wouldn’t it be better to somehow do the c_str call hidden inside the fsbridge namespace? Seems a bit odd to force devs to write ugly and unintuitive code just because mingw can’t even.

    ryanofsky commented at 3:08 pm on January 26, 2022:

    Wouldn’t it be better to somehow do the c_str call hidden inside the fsbridge namespace? Seems a bit odd to force devs to write ugly and unintuitive code just because mingw can’t even.

    I also like the idea of hiding this in the fsbridge namespace (where there is no need to use c_str() at all), which is why I originally suggested fixing this with:

    0-    typedef std::ofstream ofstream;
    1+    class ofstream : public std::ofstream
    2+    {
    3+        using std::ofstream::ofstream;
    4+        ofstream(const fs::path& p) : ofstream(static_cast<const std::filesystem::path&>(p)) {}
    5+    };
    

    But @hebasto preferred the second alternative I suggested, which was calling to c_str() so we went with that approach instead. I still do like not calling c_str() better, but don’t have a strong opinion.


    hebasto commented at 3:29 pm on January 26, 2022:
    Sorry, if my words were misleading, but I expressed my preference for c_str() over a static_cast. I’m ok if it will be hidden in fsbridge namespace.

    hebasto commented at 3:31 pm on January 26, 2022:

    I still do like not calling c_str() better,

    What reasons for?


    ryanofsky commented at 4:50 pm on January 26, 2022:

    I still do like not calling c_str() better,

    What reasons for?

    Mainly just for the reason that marco wrote #20744 (comment) that the .c_str() calls look ugly and and unsafe even if they are safe. It could be confusing that path.c_str() is safe when path.string().c_str() is unsafe, and it’s nice to just be able to pass plain path. Also just passing the path object directly avoids temporary objects. No strong preference though, and no problem with either approach.


    kiminuo commented at 5:05 pm on January 26, 2022:
    Would it be useful to summarize what one should do and what shouldn’t with the new filesystem API with regard to paths? Or is it somewhere? I mean I know ryanofsky wrote many useful comments in this PR and in others. Maybe we can have a few bullet points saying “this is OK, this is not” so that there are actually more people who can review PRs with FS changes. Just an idea. Feel free to ignore.

    ryanofsky commented at 6:32 pm on January 26, 2022:

    Would it be useful to summarize what one should do and what shouldn’t with the new filesystem API with regard to paths? Or is it somewhere? I mean I know ryanofsky wrote many useful comments in this PR and in others. Maybe we can have a few bullet points saying “this is OK, this is not” so that there are actually more people who can review PRs with FS changes. Just an idea. Feel free to ignore.

    I think main recommendation is to use fs::path object wherever possible and avoid representing paths as strings. Beyond that there is a note in developer notes:

    • Use fs::path::u8string() and fs::u8path() functions when converting path to JSON strings, not fs::PathToString and fs::PathFromString

      • Rationale: JSON strings are Unicode strings, not byte strings, and RFC8259 requires JSON to be encoded as UTF-8.

    And a detailed comment on the PathToString function saying when it should be used.

    You could write more documentation, but I think current documentation is at least not bad.

  237. martinus approved
  238. martinus commented at 5:54 pm on January 7, 2022: contributor
    tested ACK, fixes the boost 1.78 issue #23846 for me. All tests work for me, and bitcoind is syncing. Could only do light code review as I don’t know too much about the details
  239. fanquake force-pushed on Jan 10, 2022
  240. MarcoFalke commented at 9:29 am on January 10, 2022: member
     0 test  2022-01-10T08:47:25.172000Z TestFramework (INFO): Restoring wallets on node 3 using backup files 
     1 test  2022-01-10T08:47:25.172000Z TestFramework (ERROR): Assertion failed 
     2                                   Traceback (most recent call last):
     3                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\util.py", line 133, in try_rpc
     4                                       fun(*args, **kwds)
     5                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\coverage.py", line 49, in __call__
     6                                       return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
     7                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\authproxy.py", line 144, in __call__
     8                                       raise JSONRPCException(response['error'], status)
     9                                   test_framework.authproxy.JSONRPCException: copy_file: The system cannot find the path specified.:
    10"C:\Users\ContainerAdministrator\AppData\Local\Temp\test_runner_₿_🏃_20220110_084607\wallet_backup_228\node0\invalid_wallet_file.bak",
    11"C:\Users\ContainerAdministrator\AppData\Local\Temp\test_runner_?_??_20220110_084607\wallet_backup_228\node3\regtest\wallets\res0\wallet.dat" (-1)
    12                                   During handling of the above exception, another exception occurred:
    13                                   Traceback (most recent call last):
    14                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\test_framework.py", line 132, in main
    15                                       self.run_test()
    16                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\wallet_backup.py", line 195, in run_test
    17                                       self.restore_invalid_wallet()
    18                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\wallet_backup.py", line 120, in restore_invalid_wallet
    19                                       assert_raises_rpc_error(-18, error_message, node.restorewallet, wallet_name, invalid_wallet_file)
    20                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\util.py", line 124, in assert_raises_rpc_error
    21                                       assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
    22                                     File "C:\Users\ContainerAdministrator\AppData\Local\Temp\cirrus-ci-build\test\functional\test_framework\util.py", line 137, in try_rpc
    23                                       raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
    24                                   AssertionError: Unexpected JSONRPC error code -1
    
  241. fanquake commented at 9:44 am on January 10, 2022: member
    @sipsorcery @kiminuo would either of you be interested in taking a look at the native windows failures / windows related changes in general?
  242. hebasto commented at 11:18 am on January 10, 2022: member

    FWIW, both wallet_backup.py --legacy-wallet and wallet_backup.py --descriptors passed locally on Windows 10 Pro 21H1 (build 19043.1415):

     0C:\Users\hebasto\bitcoin>test\functional\wallet_backup.py --legacy-wallet
     12022-01-10T11:11:21.779000Z TestFramework (INFO): Initializing test directory C:\Users\hebasto\AppData\Local\Temp\bitcoin_func_test_k024z371
     22022-01-10T11:11:29.404000Z TestFramework (INFO): Generating initial blockchain
     32022-01-10T11:12:00.353000Z TestFramework (INFO): Creating transactions
     42022-01-10T11:12:21.280000Z TestFramework (INFO): Backing up
     52022-01-10T11:12:21.982000Z TestFramework (INFO): More transactions
     62022-01-10T11:13:09.299000Z TestFramework (INFO): Restoring wallets on node 3 using backup files
     72022-01-10T11:13:13.435000Z TestFramework (INFO): Restoring using dumped wallet
     82022-01-10T11:13:45.515000Z TestFramework (INFO): Stopping nodes
     92022-01-10T11:13:46.544000Z TestFramework (INFO): Cleaning up C:\Users\hebasto\AppData\Local\Temp\bitcoin_func_test_k024z371 on exit
    102022-01-10T11:13:46.544000Z TestFramework (INFO): Tests successful
    11
    12C:\Users\hebasto\bitcoin>test\functional\wallet_backup.py --descriptors
    132022-01-10T11:15:03.093000Z TestFramework (INFO): Initializing test directory C:\Users\hebasto\AppData\Local\Temp\bitcoin_func_test_8dguzjzh
    142022-01-10T11:15:06.702000Z TestFramework (INFO): Generating initial blockchain
    152022-01-10T11:15:12.310000Z TestFramework (INFO): Creating transactions
    162022-01-10T11:15:31.376000Z TestFramework (INFO): Backing up
    172022-01-10T11:15:31.482000Z TestFramework (INFO): More transactions
    182022-01-10T11:15:48.732000Z TestFramework (INFO): Restoring wallets on node 3 using backup files
    192022-01-10T11:15:50.200000Z TestFramework (INFO): Stopping nodes
    202022-01-10T11:15:50.440000Z TestFramework (INFO): Cleaning up C:\Users\hebasto\AppData\Local\Temp\bitcoin_func_test_8dguzjzh on exit
    212022-01-10T11:15:50.440000Z TestFramework (INFO): Tests successful
    

    and

     0C:\Users\hebasto\bitcoin>test\functional\test_runner.py --filter="wallet_backup"
     1Temporary test directory at C:\Users\hebasto\AppData\Local\Temp/test_runner_₿_🏃_20220110_132744
     2Running Unit Tests for Test Framework Modules
     3..........
     4----------------------------------------------------------------------
     5Ran 10 tests in 0.676s
     6
     7OK
     8Remaining jobs: [wallet_backup.py --legacy-wallet, wallet_backup.py --descriptors]
     91/2 - wallet_backup.py --descriptors passed, Duration: 46 s
    10Remaining jobs: [wallet_backup.py --legacy-wallet]
    112/2 - wallet_backup.py --legacy-wallet passed, Duration: 82 s
    12
    13TEST                             | STATUS    | DURATION
    14
    15wallet_backup.py --descriptors   | ✓ Passed  | 46 s
    16wallet_backup.py --legacy-wallet | ✓ Passed  | 82 s
    17
    18ALL                              | ✓ Passed  | 128 s (accumulated)
    19Runtime: 82 s
    
  243. kiminuo commented at 11:18 am on January 10, 2022: contributor

    @fanquake I’ll try my best to have a look in a day or two.

    Great job so far :)

  244. hebasto commented at 7:46 pm on January 10, 2022: member
  245. hebasto commented at 8:23 pm on January 10, 2022: member

    @sipsorcery @kiminuo would either of you be interested in taking a look at the native windows failures / windows related changes in general?

    The failing test was added in #23721. @w0xlt maybe you also could be interested in this problem?

  246. achow101 commented at 8:29 pm on January 10, 2022: member
    The Win64 failure appears to be an issue with unicode characters in the path.
  247. hebasto commented at 9:26 pm on January 10, 2022: member

    A quick fix for native Windows:

     0--- a/src/wallet/wallet.cpp
     1+++ b/src/wallet/wallet.cpp
     2@@ -377,7 +377,7 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const std::string
     3     }
     4 
     5     auto wallet_file = wallet_path / "wallet.dat";
     6-    fs::copy_file(backup_file, wallet_file);
     7+    fs::copy_file(fs::u8path(backup_file), wallet_file);
     8 
     9     auto wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
    10 
    

    Sure, it can be refactored nicely.

    Maybe, switch a type of the backup_file parameter in the RestoreWallet function from std::string to fs::path?

  248. achow101 commented at 10:03 pm on January 10, 2022: member
     0diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
     1index 64775a5ddb..41c17c53e4 100644
     2--- a/src/wallet/interfaces.cpp
     3+++ b/src/wallet/interfaces.cpp
     4@@ -561,7 +561,7 @@ public:
     5     {
     6         DatabaseStatus status;
     7 
     8-        return MakeWallet(m_context, RestoreWallet(m_context, backup_file, wallet_name, /*load_on_start=*/true, status, error, warnings));
     9+        return MakeWallet(m_context, RestoreWallet(m_context, fs::u8path(backup_file), wallet_name, /*load_on_start=*/true, status, error, warnings));
    10     }
    11     std::string getWalletDir() override
    12     {
    13diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
    14index eb912c68d5..dcf7a24b2a 100644
    15--- a/src/wallet/rpc/backup.cpp
    16+++ b/src/wallet/rpc/backup.cpp
    17@@ -1888,7 +1888,7 @@ RPCHelpMan restorewallet()
    18     bilingual_str error;
    19     std::vector<bilingual_str> warnings;
    20 
    21-    const std::shared_ptr<CWallet> wallet = RestoreWallet(context, fs::PathToString(backup_file), wallet_name, load_on_start, status, error, warnings);
    22+    const std::shared_ptr<CWallet> wallet = RestoreWallet(context, backup_file, wallet_name, load_on_start, status, error, warnings);
    23 
    24     HandleWalletError(wallet, status, error);
    25 
    26diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
    27index c6a8b3e43f..3819ec2002 100644
    28--- a/src/wallet/wallet.cpp
    29+++ b/src/wallet/wallet.cpp
    30@@ -357,12 +357,12 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string&
    31     return wallet;
    32 }
    33 
    34-std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const std::string& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
    35+std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
    36 {
    37     DatabaseOptions options;
    38     options.require_existing = true;
    39 
    40-    if (!fs::exists(fs::u8path(backup_file))) {
    41+    if (!fs::exists(backup_file)) {
    42         error = Untranslated("Backup file does not exist");
    43         status = DatabaseStatus::FAILED_INVALID_BACKUP_FILE;
    44         return nullptr;
    45diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
    46index cbcdcaf3b8..0acfe8f02a 100644
    47--- a/src/wallet/wallet.h
    48+++ b/src/wallet/wallet.h
    49@@ -60,7 +60,7 @@ std::vector<std::shared_ptr<CWallet>> GetWallets(WalletContext& context);
    50 std::shared_ptr<CWallet> GetWallet(WalletContext& context, const std::string& name);
    51 std::shared_ptr<CWallet> LoadWallet(WalletContext& context, const std::string& name, std::optional<bool> load_on_start, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings);
    52 std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string& name, std::optional<bool> load_on_start, DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings);
    53-std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const std::string& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings);
    54+std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings);
    55 std::unique_ptr<interfaces::Handler> HandleLoadWallet(WalletContext& context, LoadWalletFn load_wallet);
    56 std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
    
  249. hebasto commented at 10:08 pm on January 10, 2022: member

    A quick fix for native Windows: … Maybe, switch a type of the backup_file parameter in the RestoreWallet function from std::string to fs::path?

    Please consider #24026.

  250. fanquake force-pushed on Jan 11, 2022
  251. fanquake referenced this in commit fa74718414 on Jan 11, 2022
  252. fanquake force-pushed on Jan 11, 2022
  253. in src/fs.h:25 in 9a1ace7029 outdated
    37- * method, which worked well in the boost::filesystem implementation, but have
    38- * unsafe and unpredictable behavior on Windows in the std::filesystem
    39- * implementation (see implementation note in \ref PathToString for details).
    40+ * Path class wrapper to blocks calls to the fs::path(std::string) implicit
    41+ * constructor and the fs::path::string() method, which have unsafe and
    42+ * unpredictable behavior on Windows(see implementation note in
    


    hebasto commented at 8:24 am on January 11, 2022:

    4bccd785c921b56eed2fc21caffb0d3d684776ec nit:

    0 * unpredictable behavior on Windows (see implementation note in
    
  254. in src/fs.h:83 in 9a1ace7029 outdated
    79@@ -94,9 +80,9 @@ static inline path operator+(path p1, path p2)
    80 
    81 // Disallow implicit std::string conversion for copy_file
    82 // to avoid locale-dependent encoding on Windows.
    83-static inline void copy_file(const path& from, const path& to, copy_option options)
    84+static inline void copy_file(const path& from, const path& to, copy_options options)
    


    hebasto commented at 8:29 am on January 11, 2022:

    4bccd785c921b56eed2fc21caffb0d3d684776ec nit: although, it’s not used in our code, but technically fs::copy_file can return bool now:

    0static inline bool copy_file(const path& from, const path& to, copy_options options)
    
  255. in src/wallet/test/init_tests.cpp:76 in 9a1ace7029 outdated
    71@@ -72,6 +72,8 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
    72     BOOST_CHECK_EQUAL(walletdir, expected_path);
    73 }
    74 
    75+#ifndef WIN32
    76+// Windows does not consider "datadir///" to be a valid directory path.
    


    hebasto commented at 8:37 am on January 11, 2022:

    nit: This test checks a path with two trailing /:

    0// Windows does not consider "datadir/wallets//" to be a valid directory path.
    
  256. in configure.ac:86 in 9a1ace7029 outdated
    82@@ -83,6 +83,9 @@ AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory])
    83 dnl Check if -latomic is required for <std::atomic>
    84 CHECK_ATOMIC
    85 
    86+dnl check if -lstdc++fs is required for std::filesystem
    


    hebasto commented at 8:49 am on January 11, 2022:
    6fa8c2300ba1d05fd3afeacc3da31204cd05c189 nit: CHECK_FILESYSTEM macro actually can test -lc++fs flag as well. Therefore, the comment should mention both flags or none of them.
  257. in build-aux/m4/l_filesystem.m4:23 in 9a1ace7029 outdated
    11+
    12+AC_DEFUN([CHECK_FILESYSTEM], [
    13+
    14+  AC_LANG_PUSH(C++)
    15+
    16+  AC_MSG_CHECKING([whether std::filesystem can be used without link library])
    


    hebasto commented at 8:53 am on January 11, 2022:
    6fa8c2300ba1d05fd3afeacc3da31204cd05c189 nit: Could a comment be added with examples of currently supported tools which require -lstdc++fs or -lc++fs? This can help in the future to determine whether this macro could be dropped.
  258. hebasto commented at 9:05 am on January 11, 2022: member
  259. fanquake force-pushed on Jan 11, 2022
  260. fanquake commented at 10:48 am on January 11, 2022: member

    Also a reminder about #20744 (review)

    Done.

    Maybe you’d want to address some comments from #23522:

    All should now be addressed. I resolved in that PR.

    Fixed up current review comments as well.

  261. Fabcien referenced this in commit feb2a01c35 on Jan 11, 2022
  262. sipsorcery commented at 5:25 pm on January 11, 2022: member

    @sipsorcery @kiminuo would either of you be interested in taking a look at the native windows failures / windows related changes in general?

    My tests so far point to the Windows test failure being a pythin unicode issue.

    Running the test using wallet_backup.py always passes:

    0c:\Dev\github\sipsorcery_bitcoin>test\functional\wallet_backup.py --descriptors
    12022-01-10T21:02:34.014000Z TestFramework (INFO): Initializing test directory C:\Users\aaron\AppData\Local\Temp\bitcoin_func_test_jze1co0z
    

    Running the test using test_runner.py always fails:

    0c:\Dev\github\sipsorcery_bitcoin>test\functional\test_runner.py --filter="wallet_backup.py --descriptors"
    1Temporary test directory at C:\Users\aaron\AppData\Local\Temp/test_runner_₿_🏃_20220110_213157
    

    In the latter, failing case there are unicode characters in the path. The python exception message states it can’t encode ‘\u20bf’, but as seen in the log message above my console has no issue with it: ₿.

    I’ll keep digging.

    Update: The Python character encoding errors can be fixed with set PYTHONIOENCODING=UTF-8, e.g:

     0c:\Dev\github\sipsorcery_bitcoin>set PYTHONIOENCODING=UTF-8
     1c:\Dev\github\sipsorcery_bitcoin>test\functional\test_runner.py --filter="wallet_backup.py --descriptors"
     2Temporary test directory at C:\Users\aaron\AppData\Local\Temp/test_runner_₿_🏃_20220111_185504
     3Running Unit Tests for Test Framework Modules
     4..........
     5----------------------------------------------------------------------
     6Ran 10 tests in 0.899s
     7
     8OK
     9Remaining jobs: [wallet_backup.py --descriptors]
    101/1 - wallet_backup.py --descriptors passed, Duration: 58 s
    11
    12TEST                           | STATUS    | DURATION
    13
    14wallet_backup.py --descriptors | ✓ Passed  | 58 s
    15
    16ALL                            | ✓ Passed  | 58 s (accumulated)
    17Runtime: 58 s
    

    There are still a bunch of RPC and other errors that occur when doing a full test_runner.py but I don’t think they are introduced by this PR. I’m going to compare against master now.

  263. hebasto commented at 6:11 pm on January 11, 2022: member
    Wrt a failure of a build for Windows in Guix environment – https://gcc.gnu.org/legacy-ml/libstdc++/2011-06/msg00066.html
  264. sidhujag referenced this in commit 7f43055fac on Jan 12, 2022
  265. hebasto referenced this in commit e0ae5418cb on Jan 12, 2022
  266. sipsorcery commented at 6:40 pm on January 12, 2022: member

    @sipsorcery @kiminuo would either of you be interested in taking a look at the native windows failures / windows related changes in general? @fanquake what are the windows failures with this PR? I’d assumed it was to do with the python functional tests but I get the same failures before and after this PR.

    Relevant results of test\functional\test_runner.py:

     0wallet_watchonly.py --usecli --legacy-wallet       |  Passed  | 5 s
     1feature_backwards_compatibility.py --descriptors   |  Skipped | 1 s
     2feature_backwards_compatibility.py --legacy-wallet |  Skipped | 1 s
     3feature_bind_extra.py                              |  Skipped | 0 s
     4feature_init.py                                    |  Skipped | 3 s
     5feature_syscall_sandbox.py                         |  Skipped | 0 s
     6feature_taproot.py --previous_release              |  Skipped | 0 s
     7feature_txindex_compatibility.py                   |  Skipped | 0 s
     8mempool_compatibility.py                           |  Skipped | 0 s
     9rpc_bind.py --ipv4                                 |  Skipped | 1 s
    10rpc_bind.py --ipv6                                 |  Skipped | 0 s
    11rpc_bind.py --nonloopback                          |  Skipped | 0 s
    12wallet_upgradewallet.py --legacy-wallet            |  Skipped | 0 s
    13feature_config_args.py                             |  Failed  | 13 s
    14interface_bitcoin_cli.py --descriptors             |  Failed  | 6 s
    15interface_bitcoin_cli.py --legacy-wallet           |  Failed  | 6 s
    16interface_rpc.py                                   |  Failed  | 34 s
    17tool_wallet.py --descriptors                       |  Failed  | 19 s
    18tool_wallet.py --legacy-wallet                     |  Failed  | 15 s
    19wallet_multiwallet.py --descriptors                |  Failed  | 3 s
    20wallet_multiwallet.py --legacy-wallet              |  Failed  | 3 s
    21wallet_multiwallet.py --usecli                     |  Failed  | 3 s
    22
    23ALL                                                |  Failed  | 5971 s (accumulated)
    
  267. MarcoFalke commented at 6:41 pm on January 12, 2022: member
    I think the CI issues are fixed (telling from the green ci?)
  268. MarcoFalke commented at 6:42 pm on January 12, 2022: member
    @fanquake Is this rfm?
  269. hebasto commented at 6:54 pm on January 12, 2022: member

    @fanquake Is this rfm?

    Guix Windows build fails.

    Also a Q. in https://github.com/bitcoin/bitcoin/issues/24036

  270. achow101 commented at 8:49 pm on January 18, 2022: member
    On windows, I am hitting the assert at src/util/system.cpp:258
  271. fanquake referenced this in commit 63fc2f5cce on Jan 20, 2022
  272. fanquake force-pushed on Jan 20, 2022
  273. MarcoFalke commented at 12:46 pm on January 20, 2022: member
    You forgot to revert dc5d6b0d4793ca978f71f69ef7d6b818794676c2
  274. fanquake force-pushed on Jan 20, 2022
  275. hebasto commented at 9:35 pm on January 20, 2022: member
    I’ve restarted “ARM64 Android APK [focal]” CI build due to unrelated to this PR network issues.
  276. fanquake force-pushed on Jan 25, 2022
  277. MarcoFalke added the label DrahtBot Guix build requested on Jan 25, 2022
  278. hebasto approved
  279. hebasto commented at 10:14 am on January 25, 2022: member
    ACK 45e546c877a30a006ccb24aa465a9f6c1a96554a
  280. MarcoFalke commented at 9:45 am on January 26, 2022: member

    Seems fine to merge, but I am not yet convinced this is all correct:

    • There is a fsbridge::ofstream constructor that takes a std::string. Why is this safe, considering that usually this was passed through PathFromString? See also #23857 (comment)
    • There are a bunch of calls to c_str(), which are ugly and not exactly promoting safe code. If they are scattered around in the codebase, reviewers won’t be able to see fs::path{std::string{}.c_str()} calls, which are less safe than PathFromString? See also https://github.com/bitcoin/bitcoin/pull/20744/files#r791853189
  281. fanquake referenced this in commit 9ec56a84c3 on Jan 26, 2022
  282. fanquake referenced this in commit c6cc016679 on Jan 26, 2022
  283. fanquake referenced this in commit 21f781ad79 on Jan 26, 2022
  284. fanquake referenced this in commit 486261dfcb on Jan 26, 2022
  285. ryanofsky commented at 3:20 pm on January 26, 2022: member

    re: #20744 (comment)

    Seems fine to merge, but I am not yet convinced this is all correct:

    • There is a fsbridge::ofstream constructor that takes a std::string. Why is this safe, considering that usually this was passed through PathFromString? See also [fs: consistently use fsbridge:: for ifstream / ofstream #23857 (comment)](/bitcoin-bitcoin/23857/#issuecomment-1021995207)

    It is not safe to call the fstream std::string constructors even with PathToString! On windows, this will still do a locale conversion. Briefly skimming the code, I don’t see this happening anywhere though.

    • There are a bunch of calls to c_str(), which are ugly and not exactly promoting safe code. If they are scattered around in the codebase, reviewers won’t be able to see fs::path{std::string{}.c_str()} calls, which are less safe than PathFromString? See also https://github.com/bitcoin/bitcoin/pull/20744/files#r791853189

    To be clear, the reason why path.c_str() is safe is because it is equivalent to path.native().c_str() which returns const wchar_t* on windows not path.string().c_str() which returns const char*. Using path.native() is good, using path.string() is bad, using something.c_str() is neutral.

  286. MarcoFalke commented at 5:44 pm on January 26, 2022: member

    It is not safe to call the fstream std::string constructors even with PathToString! On windows, this will still do a locale conversion. Briefly skimming the code, I don’t see this happening anywhere though.

    I mean PathFromString. This happens https://github.com/bitcoin/bitcoin/pull/24167/files#diff-9e7b9e5b612b62329bdec3c2d522ae36dca904c291ce6192ae74c9c1b3c5827f in bench.cpp.

  287. ryanofsky commented at 6:42 pm on January 26, 2022: member

    I mean Path_From_String. This happens https://github.com/bitcoin/bitcoin/pull/24167/files#diff-9e7b9e5b612b62329bdec3c2d522ae36dca904c291ce6192ae74c9c1b3c5827f in bench.cpp.

    I see. There isn’t necessarily a bug here if command line arguments are utf-8, but the code is not ideal. More ideally benchmark::Args output_csv and output_json fields would be fs::path not std::string members, so any encoding/decoding would happen when the command line argument is parsed, not when the path is accessed.

  288. fanquake referenced this in commit d87a37a4ab on Jan 27, 2022
  289. DrahtBot added the label Needs rebase on Jan 27, 2022
  290. fanquake force-pushed on Jan 28, 2022
  291. fanquake commented at 3:49 am on January 28, 2022: member
    I’ve rebased, removed some non-essential changes, (there seemed to be issues with mingw and braced initialization), and given the discussion I have dropped the usage of .c_str() in favour of @ryanofsky’s suggested change.
  292. fanquake force-pushed on Jan 28, 2022
  293. DrahtBot removed the label Needs rebase on Jan 28, 2022
  294. in src/fs.h:23 in 6dd6f6f4df outdated
    35- * functions not present in boost. It also blocks calls to the
    36- * fs::path(std::string) implicit constructor and the fs::path::string()
    37- * method, which worked well in the boost::filesystem implementation, but have
    38- * unsafe and unpredictable behavior on Windows in the std::filesystem
    39- * implementation (see implementation note in \ref PathToString for details).
    40+ * Path class wrapper to blocks calls to the fs::path(std::string) implicit
    


    kiminuo commented at 6:49 am on January 28, 2022:
    0 * Path class wrapper to block calls to the fs::path(std::string) implicit
    

    fanquake commented at 0:44 am on February 1, 2022:
    Fixed
  295. MarcoFalke commented at 10:45 am on January 28, 2022: member
    Doesn’t compile on mingw
  296. prusnak commented at 11:04 am on January 28, 2022: contributor

    Doesn’t compile on mingw

    It seems the build failure on mingw is related to Qt 5.15.2, not this PR.

  297. MarcoFalke commented at 11:09 am on January 28, 2022: member

    Huh? https://cirrus-ci.com/task/5390848991952896?logs=ci#L8767

    0rpc/request.cpp: In function ‘bool GenerateAuthCookie(std::string*)’:
    1rpc/request.cpp:88:27: error: no matching function for call to ‘fsbridge::ofstream::open(fs::path&)’
    2   88 |     file.open(filepath_tmp);
    3      |                           ^
    
  298. prusnak commented at 11:18 am on January 28, 2022: contributor

    Huh? https://cirrus-ci.com/task/5390848991952896?logs=ci#L8767

    Ah, sorry. I missed that error. There are lots of others related to Qt 5.15.2.

  299. sidhujag referenced this in commit f9de29fcb9 on Jan 28, 2022
  300. prusnak commented at 5:56 pm on January 31, 2022: contributor

    Just for the record:

    While trying to reproduce this error I hit another error which is fixed by #24131 (I uninstalled g++-mingw-w64-x86-64 and kept only g++-mingw-w64-x86-64-posix installed on my Debian 11 Buster system).

  301. prusnak commented at 6:14 pm on January 31, 2022: contributor

    I reproduced the issue locally.

    According to reference, ofstream::open(fs::path&) has been add in C++17.

    I can see x86_64-w64-mingw32-g++-posix -std=c++17 ... in the build log, so the standard is passed correctly. Maybe mingw does not implement everything from the standard?

  302. prusnak commented at 6:44 pm on January 31, 2022: contributor

    The following changes fix the build on Mingw for me. I have not tested the resulting binaries!

    Not sure if calling c_str() is correct or desired, but at least the changes indicate where are the places which upset the compiler.

    Another and probably more clean option is to overload the ifstream::open/ofstream::open functions to also accept fs::path as the first argument.

      0diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
      1index 6f7943f34..0a16356b6 100644
      2--- a/src/qt/guiutil.cpp
      3+++ b/src/qt/guiutil.cpp
      4@@ -427,7 +427,7 @@ bool openBitcoinConf()
      5     fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
      6 
      7     /* Create the file */
      8-    fsbridge::ofstream configFile(pathConfig, std::ios_base::app);
      9+    fsbridge::ofstream configFile(pathConfig.c_str(), std::ios_base::app);
     10 
     11     if (!configFile.good())
     12         return false;
     13diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
     14index fbb4e5ddd..4fcc656de 100644
     15--- a/src/rpc/request.cpp
     16+++ b/src/rpc/request.cpp
     17@@ -85,7 +85,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
     18      */
     19     fsbridge::ofstream file;
     20     fs::path filepath_tmp = GetAuthCookieFile(true);
     21-    file.open(filepath_tmp);
     22+    file.open(filepath_tmp.c_str());
     23     if (!file.is_open()) {
     24         LogPrintf("Unable to open cookie authentication file %s for writing\n", fs::PathToString(filepath_tmp));
     25         return false;
     26@@ -110,7 +110,7 @@ bool GetAuthCookie(std::string *cookie_out)
     27     fsbridge::ifstream file;
     28     std::string cookie;
     29     fs::path filepath = GetAuthCookieFile();
     30-    file.open(filepath);
     31+    file.open(filepath.c_str());
     32     if (!file.is_open())
     33         return false;
     34     std::getline(file, cookie);
     35diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
     36index d3389c30e..ca25fcb38 100644
     37--- a/src/test/fs_tests.cpp
     38+++ b/src/test/fs_tests.cpp
     39@@ -45,37 +45,37 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
     40     fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃";
     41     fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃";
     42     {
     43-        fsbridge::ofstream file(tmpfile1);
     44+        fsbridge::ofstream file(tmpfile1.c_str());
     45         file << "bitcoin";
     46     }
     47     {
     48-        fsbridge::ifstream file(tmpfile2);
     49+        fsbridge::ifstream file(tmpfile2.c_str());
     50         std::string input_buffer;
     51         file >> input_buffer;
     52         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     53     }
     54     {
     55-        fsbridge::ifstream file(tmpfile1, std::ios_base::in | std::ios_base::ate);
     56+        fsbridge::ifstream file(tmpfile1.c_str(), std::ios_base::in | std::ios_base::ate);
     57         std::string input_buffer;
     58         file >> input_buffer;
     59         BOOST_CHECK_EQUAL(input_buffer, "");
     60     }
     61     {
     62-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::app);
     63+        fsbridge::ofstream file(tmpfile2.c_str(), std::ios_base::out | std::ios_base::app);
     64         file << "tests";
     65     }
     66     {
     67-        fsbridge::ifstream file(tmpfile1);
     68+        fsbridge::ifstream file(tmpfile1.c_str());
     69         std::string input_buffer;
     70         file >> input_buffer;
     71         BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
     72     }
     73     {
     74-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::trunc);
     75+        fsbridge::ofstream file(tmpfile2.c_str(), std::ios_base::out | std::ios_base::trunc);
     76         file << "bitcoin";
     77     }
     78     {
     79-        fsbridge::ifstream file(tmpfile1);
     80+        fsbridge::ifstream file(tmpfile1.c_str());
     81         std::string input_buffer;
     82         file >> input_buffer;
     83         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     84diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
     85index e7edadc8b..0d1d28fac 100644
     86--- a/src/test/settings_tests.cpp
     87+++ b/src/test/settings_tests.cpp
     88@@ -38,7 +38,7 @@ inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, u
     89 inline void WriteText(const fs::path& path, const std::string& text)
     90 {
     91     fsbridge::ofstream file;
     92-    file.open(path);
     93+    file.open(path.c_str());
     94     file << text;
     95 }
     96 
     97diff --git a/src/util/settings.cpp b/src/util/settings.cpp
     98index fd9fe690c..0b181a6e0 100644
     99--- a/src/util/settings.cpp
    100+++ b/src/util/settings.cpp
    101@@ -65,7 +65,7 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
    102     if (!fs::exists(path)) return true;
    103 
    104     fsbridge::ifstream file;
    105-    file.open(path);
    106+    file.open(path.c_str());
    107     if (!file.is_open()) {
    108       errors.emplace_back(strprintf("%s. Please check permissions.", fs::PathToString(path)));
    109       return false;
    110@@ -108,7 +108,7 @@ bool WriteSettings(const fs::path& path,
    111         out.__pushKV(value.first, value.second);
    112     }
    113     fsbridge::ofstream file;
    114-    file.open(path);
    115+    file.open(path.c_str());
    116     if (file.fail()) {
    117         errors.emplace_back(strprintf("Error: Unable to open settings file %s for writing", fs::PathToString(path)));
    118         return false;
    119diff --git a/src/util/system.cpp b/src/util/system.cpp
    120index 1137d4d75..c6754dbc2 100644
    121--- a/src/util/system.cpp
    122+++ b/src/util/system.cpp
    123@@ -898,7 +898,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    124     }
    125 
    126     const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
    127-    fsbridge::ifstream stream(GetConfigFile(confPath));
    128+    fsbridge::ifstream stream(GetConfigFile(confPath).c_str());
    129 
    130     // not ok to have a config file specified that cannot be opened
    131     if (IsArgSet("-conf") && !stream.good()) {
    132@@ -945,7 +945,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    133             const size_t default_includes = add_includes({});
    134 
    135             for (const std::string& conf_file_name : conf_file_names) {
    136-                fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name));
    137+                fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name).c_str());
    138                 if (conf_file_stream.good()) {
    139                     if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
    140                         return false;
    141diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
    142index 9be942e7a..b1efdd819 100644
    143--- a/src/wallet/db.cpp
    144+++ b/src/wallet/db.cpp
    145@@ -86,7 +86,7 @@ bool IsBDBFile(const fs::path& path)
    146     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    147     if (size < 4096) return false;
    148 
    149-    fsbridge::ifstream file(path, std::ios::binary);
    150+    fsbridge::ifstream file(path.c_str(), std::ios::binary);
    151     if (!file.is_open()) return false;
    152 
    153     file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
    154@@ -110,7 +110,7 @@ bool IsSQLiteFile(const fs::path& path)
    155     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    156     if (size < 512) return false;
    157 
    158-    fsbridge::ifstream file(path, std::ios::binary);
    159+    fsbridge::ifstream file(path.c_str(), std::ios::binary);
    160     if (!file.is_open()) return false;
    161 
    162     // Magic is at beginning and is 16 bytes long
    163diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
    164index 2437c415c..bd6f7d484 100644
    165--- a/src/wallet/dump.cpp
    166+++ b/src/wallet/dump.cpp
    167@@ -28,7 +28,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
    168         return false;
    169     }
    170     fsbridge::ofstream dump_file;
    171-    dump_file.open(path);
    172+    dump_file.open(path.c_str());
    173     if (dump_file.fail()) {
    174         error = strprintf(_("Unable to open %s for writing"), fs::PathToString(path));
    175         return false;
    176@@ -122,7 +122,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
    177         error = strprintf(_("Dump file %s does not exist."), fs::PathToString(dump_path));
    178         return false;
    179     }
    180-    fsbridge::ifstream dump_file(dump_path);
    181+    fsbridge::ifstream dump_file(dump_path.c_str());
    182 
    183     // Compute the checksum
    184     CHashWriter hasher(0, 0);
    185diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
    186index 3190042c5..2f2e83362 100644
    187--- a/src/wallet/rpc/backup.cpp
    188+++ b/src/wallet/rpc/backup.cpp
    189@@ -731,7 +731,7 @@ RPCHelpMan dumpwallet()
    190     }
    191 
    192     fsbridge::ofstream file;
    193-    file.open(filepath);
    194+    file.open(filepath.c_str());
    195     if (!file.is_open())
    196         throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
    197 
    
  303. prusnak commented at 8:43 pm on January 31, 2022: contributor

    Not sure if calling c_str() is correct or desired, but at least the changes indicate where are the places which upset the compiler.

    Reading more about how things are implemented in fs.h, it seems that we are actively avoiding the default conversions of std::filesystem::path to std::string, by using our own custom fs::path. Therefore the correct thing would be to call fs::PathToString(foo) instead of foo.c_str() in all places I indicated in my patch above.

    Updated patch (unfortunately, I don’t have the capacity to try whether it compiles right now):

      0diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
      1index 6f7943f34..0a16356b6 100644
      2--- a/src/qt/guiutil.cpp
      3+++ b/src/qt/guiutil.cpp
      4@@ -427,7 +427,7 @@ bool openBitcoinConf()
      5     fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
      6 
      7     /* Create the file */
      8-    fsbridge::ofstream configFile(pathConfig, std::ios_base::app);
      9+    fsbridge::ofstream configFile(fs::PathToString(pathConfig), std::ios_base::app);
     10 
     11     if (!configFile.good())
     12         return false;
     13diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
     14index fbb4e5ddd..4fcc656de 100644
     15--- a/src/rpc/request.cpp
     16+++ b/src/rpc/request.cpp
     17@@ -85,7 +85,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
     18      */
     19     fsbridge::ofstream file;
     20     fs::path filepath_tmp = GetAuthCookieFile(true);
     21-    file.open(filepath_tmp);
     22+    file.open(fs::PathToString(filepath_tmp));
     23     if (!file.is_open()) {
     24         LogPrintf("Unable to open cookie authentication file %s for writing\n", fs::PathToString(filepath_tmp));
     25         return false;
     26@@ -110,7 +110,7 @@ bool GetAuthCookie(std::string *cookie_out)
     27     fsbridge::ifstream file;
     28     std::string cookie;
     29     fs::path filepath = GetAuthCookieFile();
     30-    file.open(filepath);
     31+    file.open(fs::PathToString(filepath));
     32     if (!file.is_open())
     33         return false;
     34     std::getline(file, cookie);
     35diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
     36index d3389c30e..ca25fcb38 100644
     37--- a/src/test/fs_tests.cpp
     38+++ b/src/test/fs_tests.cpp
     39@@ -45,37 +45,37 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
     40     fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃";
     41     fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃";
     42     {
     43-        fsbridge::ofstream file(tmpfile1);
     44+        fsbridge::ofstream file(fs::PathToString(tmpfile1));
     45         file << "bitcoin";
     46     }
     47     {
     48-        fsbridge::ifstream file(tmpfile2);
     49+        fsbridge::ifstream file(fs::PathToString(tmpfile2));
     50         std::string input_buffer;
     51         file >> input_buffer;
     52         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     53     }
     54     {
     55-        fsbridge::ifstream file(tmpfile1, std::ios_base::in | std::ios_base::ate);
     56+        fsbridge::ifstream file(fs::PathToString(tmpfile1), std::ios_base::in | std::ios_base::ate);
     57         std::string input_buffer;
     58         file >> input_buffer;
     59         BOOST_CHECK_EQUAL(input_buffer, "");
     60     }
     61     {
     62-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::app);
     63+        fsbridge::ofstream file(fs::PathToString(tmpfile2), std::ios_base::out | std::ios_base::app);
     64         file << "tests";
     65     }
     66     {
     67-        fsbridge::ifstream file(tmpfile1);
     68+        fsbridge::ifstream file(fs::PathToString(tmpfile1));
     69         std::string input_buffer;
     70         file >> input_buffer;
     71         BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
     72     }
     73     {
     74-        fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::trunc);
     75+        fsbridge::ofstream file(fs::PathToString(tmpfile2), std::ios_base::out | std::ios_base::trunc);
     76         file << "bitcoin";
     77     }
     78     {
     79-        fsbridge::ifstream file(tmpfile1);
     80+        fsbridge::ifstream file(fs::PathToString(tmpfile1));
     81         std::string input_buffer;
     82         file >> input_buffer;
     83         BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
     84diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
     85index e7edadc8b..0d1d28fac 100644
     86--- a/src/test/settings_tests.cpp
     87+++ b/src/test/settings_tests.cpp
     88@@ -38,7 +38,7 @@ inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, u
     89 inline void WriteText(const fs::path& path, const std::string& text)
     90 {
     91     fsbridge::ofstream file;
     92-    file.open(path);
     93+    file.open(fs::PathToString(path));
     94     file << text;
     95 }
     96 
     97diff --git a/src/util/settings.cpp b/src/util/settings.cpp
     98index fd9fe690c..0b181a6e0 100644
     99--- a/src/util/settings.cpp
    100+++ b/src/util/settings.cpp
    101@@ -65,7 +65,7 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
    102     if (!fs::exists(path)) return true;
    103 
    104     fsbridge::ifstream file;
    105-    file.open(path);
    106+    file.open(fs::PathToString(path));
    107     if (!file.is_open()) {
    108       errors.emplace_back(strprintf("%s. Please check permissions.", fs::PathToString(path)));
    109       return false;
    110@@ -108,7 +108,7 @@ bool WriteSettings(const fs::path& path,
    111         out.__pushKV(value.first, value.second);
    112     }
    113     fsbridge::ofstream file;
    114-    file.open(path);
    115+    file.open(fs::PathToString(path));
    116     if (file.fail()) {
    117         errors.emplace_back(strprintf("Error: Unable to open settings file %s for writing", fs::PathToString(path)));
    118         return false;
    119diff --git a/src/util/system.cpp b/src/util/system.cpp
    120index 1137d4d75..c6754dbc2 100644
    121--- a/src/util/system.cpp
    122+++ b/src/util/system.cpp
    123@@ -898,7 +898,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    124     }
    125 
    126     const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
    127-    fsbridge::ifstream stream(GetConfigFile(confPath));
    128+    fsbridge::ifstream stream(fs::PathToString(GetConfigFile(confPath)));
    129 
    130     // not ok to have a config file specified that cannot be opened
    131     if (IsArgSet("-conf") && !stream.good()) {
    132@@ -945,7 +945,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
    133             const size_t default_includes = add_includes({});
    134 
    135             for (const std::string& conf_file_name : conf_file_names) {
    136-                fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name));
    137+                fsbridge::ifstream conf_file_stream(fs::PathToString(GetConfigFile(conf_file_name)));
    138                 if (conf_file_stream.good()) {
    139                     if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
    140                         return false;
    141diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
    142index 9be942e7a..b1efdd819 100644
    143--- a/src/wallet/db.cpp
    144+++ b/src/wallet/db.cpp
    145@@ -86,7 +86,7 @@ bool IsBDBFile(const fs::path& path)
    146     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    147     if (size < 4096) return false;
    148 
    149-    fsbridge::ifstream file(path, std::ios::binary);
    150+    fsbridge::ifstream file(fs::PathToString(path), std::ios::binary);
    151     if (!file.is_open()) return false;
    152 
    153     file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
    154@@ -110,7 +110,7 @@ bool IsSQLiteFile(const fs::path& path)
    155     if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
    156     if (size < 512) return false;
    157 
    158-    fsbridge::ifstream file(path, std::ios::binary);
    159+    fsbridge::ifstream file(fs::PathToString(path), std::ios::binary);
    160     if (!file.is_open()) return false;
    161 
    162     // Magic is at beginning and is 16 bytes long
    163diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
    164index 2437c415c..bd6f7d484 100644
    165--- a/src/wallet/dump.cpp
    166+++ b/src/wallet/dump.cpp
    167@@ -28,7 +28,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
    168         return false;
    169     }
    170     fsbridge::ofstream dump_file;
    171-    dump_file.open(path);
    172+    dump_file.open(fs::PathToString(path));
    173     if (dump_file.fail()) {
    174         error = strprintf(_("Unable to open %s for writing"), fs::PathToString(path));
    175         return false;
    176@@ -122,7 +122,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
    177         error = strprintf(_("Dump file %s does not exist."), fs::PathToString(dump_path));
    178         return false;
    179     }
    180-    fsbridge::ifstream dump_file(dump_path);
    181+    fsbridge::ifstream dump_file(fs::PathToString(dump_path));
    182 
    183     // Compute the checksum
    184     CHashWriter hasher(0, 0);
    185diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
    186index 3190042c5..2f2e83362 100644
    187--- a/src/wallet/rpc/backup.cpp
    188+++ b/src/wallet/rpc/backup.cpp
    189@@ -731,7 +731,7 @@ RPCHelpMan dumpwallet()
    190     }
    191 
    192     fsbridge::ofstream file;
    193-    file.open(filepath);
    194+    file.open(fs::PathToString(filepath));
    195     if (!file.is_open())
    196         throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
    197 
    
  304. ryanofsky commented at 8:53 pm on January 31, 2022: member

    Reading more about how things are implemented in fs.c, it seems that we are actively avoiding the default conversions of std::filesystem::path to std::string, by using our own custom fs::path. Therefore the correct thing would be to call fs::PathToString(foo) instead of foo.c_str() in all places I indicated in my patch above.

    To be clear we are actively avoiding converting paths to narrow strings, because on windows it will result in possibly incorrect encodings using the current windows code page. Calling fs::PathToString would also be incorrect and does not avoid the problem, because it would convert the wide string to a narrow string as utf8, but then narrow string would be decoded back to a wide string using the current windows code page again (which would be incorrect if the code page is not also UTF-8). Calling path.c_str() is correct because it is equivalent to path.native().c_str() and avoids encoding / decoding whatsoever.

  305. ryanofsky commented at 9:04 pm on January 31, 2022: member

    @fanquake To fix the windows ifstream errors https://cirrus-ci.com/task/5390848991952896?logs=ci#L8810 like:

    0wallet/db.cpp: In function bool wallet::IsSQLiteFile(const fs::path&):
    1wallet/db.cpp:113:51: error: no matching function for call to std::basic_ifstream<char>::basic_ifstream(const fs::path&, const openmode&)
    2  113 |     fsbridge::ifstream file(path, std::ios::binary);
    

    You could either define an fsbridge::ifstream class similar to the fsbridge::ofstream class defining an fs::path constructor:

    https://github.com/bitcoin/bitcoin/blob/6dd6f6f4df06f61bd0d90db1247428b9d6a6626e/src/fs.h#L177-L182

    Or, you could pass path.c_str() to ifstream constructors (which is equivalent to path.native().c_str() and avoids encoding/decoding)`

  306. fanquake force-pushed on Feb 1, 2022
  307. fanquake force-pushed on Feb 1, 2022
  308. fanquake commented at 1:18 am on February 1, 2022: member

    You could either define an fsbridge::ifstream class similar to the fsbridge::ofstream class defining an fs::path constructor:

    I’ve done this, as it seems everyone is in favour of keeping changes constrained to fs.* rather than using c_str() over the codebase.

  309. fanquake force-pushed on Feb 1, 2022
  310. fanquake force-pushed on Feb 1, 2022
  311. prusnak commented at 8:33 am on February 1, 2022: contributor
  312. hebasto commented at 8:16 pm on February 2, 2022: member

    To fix MinGW build, suggesting the following patch:

     0--- a/src/fs.h
     1+++ b/src/fs.h
     2@@ -175,18 +175,26 @@ namespace fsbridge {
     3 
     4     std::string get_filesystem_error_message(const fs::filesystem_error& e);
     5 
     6-    class ifstream : public std::ifstream
     7+    struct ifstream : public std::ifstream
     8     {
     9-        using std::ifstream::ifstream;
    10-    public:
    11-        ifstream(const fs::path& p) : ifstream(static_cast<const std::filesystem::path&>(p)) {}
    12+        ifstream() = default;
    13+        explicit ifstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in)
    14+            : std::ifstream(static_cast<const std::filesystem::path&>(p), mode) {}
    15+        void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in)
    16+        {
    17+            std::ifstream::open(static_cast<const std::filesystem::path&>(p), mode);
    18+        }
    19     };
    20 
    21-    class ofstream : public std::ofstream
    22+    struct ofstream : public std::ofstream
    23     {
    24-        using std::ofstream::ofstream;
    25-    public:
    26-        ofstream(const fs::path& p) : ofstream(static_cast<const std::filesystem::path&>(p)) {}
    27+        ofstream()  = default;
    28+        explicit ofstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out)
    29+            : std::ofstream(static_cast<const std::filesystem::path&>(p), mode) {}
    30+        void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out)
    31+        {
    32+            std::ofstream::open(static_cast<const std::filesystem::path&>(p), mode);
    33+        }
    34     };
    35 };
    36 
    

    A successful CI build is here: https://cirrus-ci.com/build/6256816739844096

  313. hebasto commented at 9:36 pm on February 2, 2022: member

    I’ve done some research, and suggesting a–seemingly more elegant–solution: s/fsbridge::{i,o}fstream/std::{i,o}fstream/g, and apply the following patch:

     0--- a/src/fs.h
     1+++ b/src/fs.h
     2@@ -51,6 +51,11 @@ public:
     3 
     4     // Disallow std::string conversion method to avoid locale-dependent encoding on windows.
     5     std::string string() const = delete;
     6+
     7+    // Required for path overloads in <fstream>.
     8+    // See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=96e0367ead5d8dcac3bec2865582e76e2fbab190
     9+    path& make_preferred() { std::filesystem::path::make_preferred(); return *this; }
    10+    path filename() const { return std::filesystem::path::filename(); }
    11 };
    12 
    13 // Disallow implicit std::string conversion for absolute to avoid
    14@@ -174,20 +179,6 @@ namespace fsbridge {
    15     };
    16 
    17     std::string get_filesystem_error_message(const fs::filesystem_error& e);
    18-
    19-    class ifstream : public std::ifstream
    20-    {
    21-        using std::ifstream::ifstream;
    22-    public:
    23-        ifstream(const fs::path& p) : ifstream(static_cast<const std::filesystem::path&>(p)) {}
    24-    };
    25-
    26-    class ofstream : public std::ofstream
    27-    {
    28-        using std::ofstream::ofstream;
    29-    public:
    30-        ofstream(const fs::path& p) : ofstream(static_cast<const std::filesystem::path&>(p)) {}
    31-    };
    32 };
    33 
    34 // Disallow path operator<< formatting in tinyformat to avoid locale-dependent
    

    A successful CI build is here: https://cirrus-ci.com/build/5354194935742464

  314. fanquake force-pushed on Feb 3, 2022
  315. fanquake force-pushed on Feb 3, 2022
  316. fanquake force-pushed on Feb 3, 2022
  317. fanquake commented at 5:48 am on February 3, 2022: member
    @hebasto I’ve adapted to take your second approach. Guix builds for all (working) HOSTS will be added to the PR description shortly.
  318. hebasto commented at 8:26 am on February 3, 2022: member

    Tested db2b9123bba80829a01a32054f4736a5333d5f75.

    1. Cross-compiled Windows binaries work fine on Windows 10 Pro 21H1 (build 19043.1466).
    2. On Windows 10 Pro 21H1 (build 19043.1466) being compiled with MSVC and run flawlessly (also see #24065 (comment)).
  319. hebasto commented at 9:34 am on February 3, 2022: member

    Guix builds:

     0$ find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum
     1640eb4085dbb9cfe2f0cb2c703fe8f3229274f3c1fa6d65ae3bbc59e5c56ea34  guix-build-db2b9123bba8/output/aarch64-linux-gnu/SHA256SUMS.part
     24d45614059ef643196a32c5c3260759e535a79a1d59b3fa341c17337785323f1  guix-build-db2b9123bba8/output/aarch64-linux-gnu/bitcoin-db2b9123bba8-aarch64-linux-gnu-debug.tar.gz
     3f382e74bdf0f84016d7fc608db8f445d0ecab3baea2393141c801916120f9d8f  guix-build-db2b9123bba8/output/aarch64-linux-gnu/bitcoin-db2b9123bba8-aarch64-linux-gnu.tar.gz
     4e5ff995a3bc3ee4fb81c5ff162997721fa64d76d958a5e90efbd322be876e5b7  guix-build-db2b9123bba8/output/arm-linux-gnueabihf/SHA256SUMS.part
     5249d90bd4fd97062d5629f5408dc05b56c053ae1d826f5909a9576e926666dea  guix-build-db2b9123bba8/output/arm-linux-gnueabihf/bitcoin-db2b9123bba8-arm-linux-gnueabihf-debug.tar.gz
     6714dfd377c314e5466560ab47d857e480bb6aa105671241c4a85ae20527ae54a  guix-build-db2b9123bba8/output/arm-linux-gnueabihf/bitcoin-db2b9123bba8-arm-linux-gnueabihf.tar.gz
     7518d62f5bcb34939b7a36cb642f5e05465d253b8de6d16ccf25661f326abfe5d  guix-build-db2b9123bba8/output/arm64-apple-darwin/SHA256SUMS.part
     8474d14000d329381ca52991f4f8ebab6feab8a7afe64cf21d87b267f9a922065  guix-build-db2b9123bba8/output/arm64-apple-darwin/bitcoin-db2b9123bba8-arm64-apple-darwin.tar.gz
     9733533dbd271ec8088a2bf0ad8e6e34b0aedba2dcb98defc2d333f230582d146  guix-build-db2b9123bba8/output/arm64-apple-darwin/bitcoin-db2b9123bba8-osx-unsigned.dmg
    10f4f39117cb449ba3433cdf0456cdd7b40f322ba42dbc94b8e9fd6529d57ed11f  guix-build-db2b9123bba8/output/arm64-apple-darwin/bitcoin-db2b9123bba8-osx-unsigned.tar.gz
    1177b751ea929e38aba0197e6926c18eb4d5a95a9ed44036600148e48711fd409f  guix-build-db2b9123bba8/output/dist-archive/bitcoin-db2b9123bba8.tar.gz
    12e7ecd03ae71d22f30a8c1852880b616412edbb4b84dca707fefc9ef02cedf09b  guix-build-db2b9123bba8/output/powerpc64-linux-gnu/SHA256SUMS.part
    13266e70594b214a73aeb885d180cfe7e9c3297f62af7d56aa3ea607f290f6e38c  guix-build-db2b9123bba8/output/powerpc64-linux-gnu/bitcoin-db2b9123bba8-powerpc64-linux-gnu-debug.tar.gz
    143fcae959ea5d21fe4224965578cae26f6027c40699f827daf34f65cc877623f2  guix-build-db2b9123bba8/output/powerpc64-linux-gnu/bitcoin-db2b9123bba8-powerpc64-linux-gnu.tar.gz
    15611f7b329bb03043ffd9d360df107b026b38b605db69a7c03d9bd2d2950f0b24  guix-build-db2b9123bba8/output/powerpc64le-linux-gnu/SHA256SUMS.part
    16dba36af32dd69bf5a0f0397fe397161ef011501d16f613606da5e795728efe53  guix-build-db2b9123bba8/output/powerpc64le-linux-gnu/bitcoin-db2b9123bba8-powerpc64le-linux-gnu-debug.tar.gz
    17ea68215c24acb24b5b723917140b0496da054eae3e25308b5ecad3fcfc0ce4f4  guix-build-db2b9123bba8/output/powerpc64le-linux-gnu/bitcoin-db2b9123bba8-powerpc64le-linux-gnu.tar.gz
    1853ecc1a3b2cafd0a515c27e284ca1b0623bbd79b9a2d7b3f12c60fb4bc99161a  guix-build-db2b9123bba8/output/riscv64-linux-gnu/SHA256SUMS.part
    195c9f2979bb85bf897858cef3ca128d1166f594123c07c5abc9fe6a69ed18dfbf  guix-build-db2b9123bba8/output/riscv64-linux-gnu/bitcoin-db2b9123bba8-riscv64-linux-gnu-debug.tar.gz
    2095fb281e74c81fd01ef16426f216e8f59240481728c5bfc9c9bd9c2eb0dd870f  guix-build-db2b9123bba8/output/riscv64-linux-gnu/bitcoin-db2b9123bba8-riscv64-linux-gnu.tar.gz
    216ea751f76e5c6eb95200728bb45c1f2d2eab54259e96899cf2b3582bd47f6124  guix-build-db2b9123bba8/output/x86_64-apple-darwin/SHA256SUMS.part
    22a8a5d1275f634824aea61925f05f81dff4138c909e89b94a9d432f51d13e3377  guix-build-db2b9123bba8/output/x86_64-apple-darwin/bitcoin-db2b9123bba8-osx-unsigned.dmg
    2363c99793e3f92da8f935571b0633abb273783667e7be834981da1c771f7a4036  guix-build-db2b9123bba8/output/x86_64-apple-darwin/bitcoin-db2b9123bba8-osx-unsigned.tar.gz
    24a13dae89eec4568eae3c275009bb61993b5ca28aa264d209c1f47f68ceda9b9d  guix-build-db2b9123bba8/output/x86_64-apple-darwin/bitcoin-db2b9123bba8-osx64.tar.gz
    25fc917f27708fcb014844445f54715b97a76aae4c202472768e08f84190a8a968  guix-build-db2b9123bba8/output/x86_64-linux-gnu/SHA256SUMS.part
    26e23b1c6bf6fef11490c8cbea5c8a4014519a6b9e39865e5c0ea70608231382bf  guix-build-db2b9123bba8/output/x86_64-linux-gnu/bitcoin-db2b9123bba8-x86_64-linux-gnu-debug.tar.gz
    2773cfb2c4f37b8040beb78289712cd752a751ef196fce878f7db27665fa85b426  guix-build-db2b9123bba8/output/x86_64-linux-gnu/bitcoin-db2b9123bba8-x86_64-linux-gnu.tar.gz
    
  320. hebasto commented at 9:40 am on February 3, 2022: member

    @fanquake

    Guix builds for all (working) HOSTS will be added to the PR description shortly.

    It seems they lack a build for aarch64-linux-gnu arch.

  321. fanquake commented at 10:02 am on February 3, 2022: member

    It seems they lack a build for aarch64-linux-gnu arch.

    Added.

  322. build: add support for std::filesystem
    Add a macro to check if linking with -lstdc++fs or -lc++fs is required.
    ffc89d1f21
  323. refactor: replace boost::filesystem with std::filesystem
    Warning: Replacing fs::system_complete calls with fs::absolute calls
    in this commit may cause minor changes in behaviour because fs::absolute
    no longer strips trailing slashes; however these changes are believed to
    be safe.
    
    Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
    Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
    41d7166c8a
  324. build: remove boost::filesystem usage b87f9c5edf
  325. build: remove Boost::system usage 07269321f3
  326. in build-aux/m4/l_filesystem.m4:6 in db2b9123bb outdated
    0@@ -0,0 +1,47 @@
    1+dnl Copyright (c) 2022 The Bitcoin Core developers
    2+dnl Distributed under the MIT software license, see the accompanying
    3+dnl file COPYING or http://www.opensource.org/licenses/mit-license.php.
    4+
    5+# GCC 9.1 and earlier requires -lstdc++fs
    6+# Clang 9.0 (libc++) and earlier requires -lc++fs
    


    hebasto commented at 10:18 am on February 3, 2022:

    def4c1704d27754398375880d9a0ba8f31a0464d

    This comment makes me think that using CXX='clang++-9 -stdlib=libc++' ends with linking -lc++fs. That is not the case. Tested on tested on Linux Mint 20.2 (x86_64) with clang-8 and clang-9.

    See https://releases.llvm.org/9.0.0/projects/libcxx/docs/UsingLibcxx.html#using-filesystem

    Maybe

    0# Prior to LLVM 9.0, libc++ provides the implementation of the filesystem library in a separate static library,
    1# and using of <filesystem> requires to link -lc++fs.
    

    or something similar with better wording?


    hebasto commented at 10:30 am on February 3, 2022:
    Similar concerns are about gcc comment above as according to https://gcc.gnu.org/gcc-9/changes.html gcc-9 does not require -lstdc++fs.

    fanquake commented at 10:32 am on February 3, 2022:

    I don’t think we need to copy paste all of that in here. We can just change it to:

    0# Clang 8.0 (libc++) and earlier requires -lc++fs
    

    hebasto commented at 10:36 am on February 3, 2022:

    Hmm, unexpected:

    0$ ./configure CC=gcc-8 CXX=g++-8
    1...
    2checking whether std::filesystem can be used without link library... yes
    3...
    

    fanquake commented at 10:38 am on February 3, 2022:
    Addressed both.

    fanquake commented at 10:42 am on February 3, 2022:

    Hmm, unexpected:

    If you’ve got other GCC’s installed, it’s likely not using version 8 of the standard library. Have a look at the verbose compiler output.

  327. fanquake force-pushed on Feb 3, 2022
  328. laanwj commented at 12:15 pm on February 3, 2022: member

    Code review ACK 07269321f38e46e9e02f16d7cd135ea90692638d

    I’ve done this, as it seems everyone is in favour of keeping changes constrained to fs.* rather than using c_str() over the codebase.

    Definitely.

  329. hebasto commented at 12:59 pm on February 3, 2022: member
    Tested 07269321f38e46e9e02f16d7cd135ea90692638d on macOS Catalina 10.15.7 (19H1713): being compiled with Homebrew’s packages and run flawlessly.
  330. hebasto commented at 1:14 pm on February 3, 2022: member

    Tested 07269321f38e46e9e02f16d7cd135ea90692638d on Ubuntu Bionic 18.04.

    The third commit b87f9c5edf3895df9650131fcf8551c3ad1d7301 compiles ok, but the last commit fails:

     0$ ./autogen.sh
     1$ ./configure --without-gui --without-bdb CC=gcc-8 CXX=g++-8
     2$ make clean
     3$ make
     4...
     5libbitcoin_util.a(libbitcoin_util_a-system.o): In function `boost::system::error_category::std_category::equivalent(std::error_code const&, int) const':
     6/usr/include/boost/system/error_code.hpp:686: undefined reference to `boost::system::generic_category()'
     7/usr/include/boost/system/error_code.hpp:689: undefined reference to `boost::system::generic_category()'
     8/usr/include/boost/system/error_code.hpp:701: undefined reference to `boost::system::generic_category()'
     9libbitcoin_util.a(libbitcoin_util_a-system.o): In function `boost::system::error_category::std_category::equivalent(int, std::error_condition const&) const':
    10/usr/include/boost/system/error_code.hpp:656: undefined reference to `boost::system::generic_category()'
    11/usr/include/boost/system/error_code.hpp:659: undefined reference to `boost::system::generic_category()'
    12libbitcoin_util.a(libbitcoin_util_a-system.o):/usr/include/boost/system/error_code.hpp:206: more undefined references to `boost::system::generic_category()' follow
    13libbitcoin_util.a(libbitcoin_util_a-system.o): In function `__static_initialization_and_destruction_0':
    14/usr/include/boost/system/error_code.hpp:210: undefined reference to `boost::system::system_category()'
    15libbitcoin_util.a(libbitcoin_util_a-system.o): In function `_GLOBAL__sub_I_BITCOIN_CONF_FILENAME':
    16/usr/include/boost/asio/error.hpp:230: undefined reference to `boost::system::system_category()'
    17collect2: error: ld returned 1 exit status
    18Makefile:5708: recipe for target 'bitcoind' failed
    19make[2]: *** [bitcoind] Error 1
    20...
    
  331. MarcoFalke commented at 1:29 pm on February 3, 2022: member

    Concept ACK 07269321f38e46e9e02f16d7cd135ea90692638d 🎀

    Signature:

     0-----BEGIN PGP SIGNED MESSAGE-----
     1Hash: SHA512
     2
     3Concept ACK 07269321f38e46e9e02f16d7cd135ea90692638d 🎀
     4-----BEGIN PGP SIGNATURE-----
     5
     6iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
     7pUgofAv+JlnSIf2qICI4sGlwHKVaOFpBXTij+BiUO/deMkVVE6l34iQxvziFRLLo
     8gxLGHEZuuvpT6Gg7WK0d/Fn0c3fHvywtF7DCiq299f/8I/Z7y8fKP3d7e2uL57I6
     9anIWW1QDr0FggeE/oR5Llz6pidZcSfvDDCff/8j1uMng9p/9RKapnNcJFT0ax0mv
    10nXkKa2axowGT8TkKGs80YPTpPXAPS7Q6sACta6JmRqcRG7ulWVjia5IANWC7aq/A
    1195HoLJdQ6X4khvQ6627k+vT0eSoPSL7i8dR2S10VBu+aNPFxRgMK2eEBzVLuQ3JN
    12sFWoW8M3g3dqENu1bsp7zHHmuwcxwn0PeNpKciEp54pooQBNBwWHGjOe5+5gsaar
    13klFxVV5XjeryXvlWcHjW0J1t7Sr5VCFs9MCsRZilOuyMS2i8FzAbpV6q2mxXue2Y
    14y6uT2VIbyNPpQwznoiQIiYgCfHRIYaRB4sUoyoAIsJmKDxA4TSoxt2XW23RYrQru
    15qz+ahi/U
    16=kXE8
    17-----END PGP SIGNATURE-----
    
  332. prusnak commented at 1:33 pm on February 3, 2022: contributor

    Tested 0726932 on Ubuntu Bionic 18.04. @hebasto Does this happen with clean checkout? Maybe make clean left some artefacts.

  333. hebasto commented at 1:36 pm on February 3, 2022: member

    Tested 0726932 on Ubuntu Bionic 18.04.

    @hebasto Does this happen with clean checkout? Maybe make clean left some artefacts.

    The same after git clean -xdff.

  334. MarcoFalke commented at 1:44 pm on February 3, 2022: member
    This only happens with system libs and not depends?
  335. hebasto commented at 1:47 pm on February 3, 2022: member

    This only happens with system libs and not depends?

    CI builds with depends, right?

  336. MarcoFalke commented at 1:47 pm on February 3, 2022: member
    Yes
  337. in src/test/util_tests.cpp:79 in 41d7166c8a outdated
    70@@ -70,9 +71,12 @@ BOOST_AUTO_TEST_CASE(util_datadir)
    71     args.ClearPathCache();
    72     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
    73 
    74+#ifndef WIN32
    75+    // Windows does not consider "datadir/.//" to be a valid directory path.
    76     args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
    77     args.ClearPathCache();
    78     BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
    79+#endif
    


    ryanofsky commented at 2:00 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    The way this is written, it’s confusing and vague about windows test behavior. Would change this to actually check windows behavior instead of skipping it, and also add more detail to the comment:

     0    args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
     1    args.ClearPathCache();
     2#ifndef WIN32
     3    BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
     4#else
     5    // Windows does not consider "datadir/.//" to be a valid directory path, so
     6    // the check to see if the directory exists returns false on windows, and
     7    // GetDataDirBase() returns nothing. When this test was originally written
     8    // GetDataDirBase() function stripped trailing "/" slashes, so the test was
     9    // the same on all platforms. But as of [#20744](/bitcoin-bitcoin/20744/), trailing slashes are no
    10    // longer stripped (because it would have complicated the GetDataDirBase
    11    // implementation), so the test is now platform-specific.
    12    BOOST_CHECK(args.GetDataDirBase().empty());
    13#endif
    

    I think trying to clarify things here is worth it, because this test is already very confusing (every time I look at it my brain hurts), and most developers are not using windows, so problems that only happen on windows are especially painful to deal with.

    (This is also closer to originally suggested fix from #20744#pullrequestreview-785640725)


    MarcoFalke commented at 2:07 pm on February 3, 2022:
    I think the goal was to not allow the unit test to do random crap to the root dir /, outside their assigned m_path_root

    ryanofsky commented at 2:51 pm on February 3, 2022:

    re: #20744 (review)

    I think the goal was to not allow the unit test to do random crap to the root dir /, outside their assigned m_path_root

    I don’t think that’s what’s happening here. In any case:

    • It is good to replace a vague comment with a specific comment.
    • The point of the test is to ensure bitcoin has sane behavior if user uses extra trailing “./” characters in a custom datadir on linux. If we care about this behavior on linux, I don’t think think we should say anything goes on windows and not check behavior there. Windows is a 30+ year old operating system with stable path semantics. If path semantics somehow do change, it is a good thing if the test fails, and the test has an understandable comment, we decide can what to do about it.

    ryanofsky commented at 2:59 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    I think this change might be able to be reverted actually, because since this test was disabled a StripRedundantLastElementsOfPath call was added to GetDataDir. It looks like the call was added in the Dec 23 push #20744#event-5807965413 https://github.com/bitcoin/bitcoin/compare/f53be20eade794e55470473f03a8d05d57691c87..2c990b05fae7e1bfef2d3f59044c24274812c559#diff-19427b0dd1a791adc728c82e88f267751ba4f1c751e19262cac03cccd2822216R438 without an explanation

  338. in src/util/system.cpp:252 in 41d7166c8a outdated
    248@@ -243,7 +249,7 @@ namespace {
    249 fs::path StripRedundantLastElementsOfPath(const fs::path& path)
    250 {
    251     auto result = path;
    252-    while (fs::PathToString(result.filename()) == ".") {
    253+    while (result.filename().empty() || fs::PathToString(result.filename()) == ".") {
    


    ryanofsky commented at 2:16 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    Note: Just to explain this change, it’s needed because std path class, unlike boost path class treats paths with trailing slashes as having a final "" component, instead of a final "." component.

    This change was originally suggested #20744 (review), and a test program for this behavior is https://godbolt.org/z/voadYc8M1)


    kiminuo commented at 2:29 pm on February 3, 2022:
    (Unfortunately, links like #20744 (review) do not work for me. There are probably too much comments in this PR or it’s resolved. I don’t know.)

    ryanofsky commented at 2:54 pm on February 3, 2022:

    (Unfortunately, links like #20744 (comment) do not work for me. There are probably too much comments in this PR or it’s resolved. I don’t know.)

    Github struggles with long discusions threads, and these links often they stop working and then start working again. They’re the same link used in github notification emails so not special.

  339. kiminuo commented at 2:18 pm on February 3, 2022: contributor

    Compiled and run on Windows 11:

    image

    Seems to work fine 🎉

  340. in src/util/system.cpp:418 in 41d7166c8a outdated
    420@@ -415,7 +421,6 @@ const fs::path& ArgsManager::GetBlocksDirPath() const
    421     path /= fs::PathFromString(BaseParams().DataDir());
    422     path /= "blocks";
    423     fs::create_directories(path);
    424-    path = StripRedundantLastElementsOfPath(path);
    


    ryanofsky commented at 2:20 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    Note: Just to explain this change, this line is deleted because the path variable is set 2 lines above with literal “blocks” last element, so this line would never do anything, even before this PR. Earlier discussion was #20744 (review)

  341. kiminuo commented at 2:22 pm on February 3, 2022: contributor
    @hebasto I tried to compile on Ubuntu 18.04.6 LTS with your instructions and I can see the same result.
  342. MarcoFalke commented at 2:37 pm on February 3, 2022: member

    I think this is ready for merge. Any developers (hopefully none) on Ubuntu Bionic can:

    • Upgrade to a more recent Ubuntu
    • Revert the last commit locally
    • Build from depends
    • Install a more recent boost

    Merging now gives more time for testing in master and we still have about 3 weeks to decide how to fix the build on Ubuntu Bionic, with the easiest being a clean revert of the last commit.

    Any other minor fixups (like in the tests) can also land in the next 3 weeks.

  343. hebasto commented at 2:40 pm on February 3, 2022: member

    Guix builds:

     0$ find guix-build-$(git rev-parse --short=12 HEAD)/output/ -type f -print0 | env LC_ALL=C sort -z | xargs -r0 sha256sum
     1c1f9b326f9be4140f00cebeae5ff8de428a2fb8ecced539fcc36c53f53bfecf4  guix-build-07269321f38e/output/aarch64-linux-gnu/SHA256SUMS.part
     2b44aca3bcf5ea92a3a6c48c24d6f85576f425f59b73528d4d00c20e950cf2128  guix-build-07269321f38e/output/aarch64-linux-gnu/bitcoin-07269321f38e-aarch64-linux-gnu-debug.tar.gz
     327a5553f7bd14797293fc40c5fb131c91e98a61d5481a283f13a1d0497eb5ed8  guix-build-07269321f38e/output/aarch64-linux-gnu/bitcoin-07269321f38e-aarch64-linux-gnu.tar.gz
     499e55a88823f6095864a09c9eaa824e24d9ec527380eb394f751c7205b930f69  guix-build-07269321f38e/output/arm-linux-gnueabihf/SHA256SUMS.part
     5b720b2724fa47fde584f58ed3b587f1d1183523540777fd367ab7e582605cfea  guix-build-07269321f38e/output/arm-linux-gnueabihf/bitcoin-07269321f38e-arm-linux-gnueabihf-debug.tar.gz
     6c19c247f4e9e0d7f888ac8ba9de1c12d382f48fa828a685d4fe02818a18abd1f  guix-build-07269321f38e/output/arm-linux-gnueabihf/bitcoin-07269321f38e-arm-linux-gnueabihf.tar.gz
     755b49ccb38de03bb95101354a16fd8d2190abede5ccc0d9b00b40c0cd526a2f6  guix-build-07269321f38e/output/arm64-apple-darwin/SHA256SUMS.part
     8baa44752470a6be9acae1c2f8fd1b9bc37afb00971787ea11fbaeddc9ab7c4aa  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-arm64-apple-darwin.tar.gz
     9ad7df4d8026d5bcce1321cdccc2e1820e8a8bb7e1064ed16e20a7ea354057fd2  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.dmg
    10f342066dc34a14d67c47779a2413a14633a996e8e7ddca89ae0184e23ef99efd  guix-build-07269321f38e/output/arm64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.tar.gz
    11f6905346a5d48f57805fb062d0247ab5007c89047070a0b3125941dd1a2b8aa6  guix-build-07269321f38e/output/dist-archive/bitcoin-07269321f38e.tar.gz
    12a1f6c4b2b118dbd89770801f0bcffd2218b82df408cd227e34c40493469bb7a2  guix-build-07269321f38e/output/powerpc64-linux-gnu/SHA256SUMS.part
    13ba8359426e523bf013d93579c1bedc57380214c8170a9743b64ec1a8a3bbccbf  guix-build-07269321f38e/output/powerpc64-linux-gnu/bitcoin-07269321f38e-powerpc64-linux-gnu-debug.tar.gz
    14b0bb500c274a683ea28ecbc1e8f18c618a9f8acb00045f80ae43c515288402c0  guix-build-07269321f38e/output/powerpc64-linux-gnu/bitcoin-07269321f38e-powerpc64-linux-gnu.tar.gz
    1538c85e9589e092cd3aa08996aa383c0ccd5c73208943389741355a6eb7f72537  guix-build-07269321f38e/output/powerpc64le-linux-gnu/SHA256SUMS.part
    1650fcba7942ff48d91e84c093fda0affc17e46167fe1d5137c6e14c5c41f289d1  guix-build-07269321f38e/output/powerpc64le-linux-gnu/bitcoin-07269321f38e-powerpc64le-linux-gnu-debug.tar.gz
    17fa08ef1ceca072e014faa95ffee945954b2976fa28f90926b87ab0e5f15f8ca5  guix-build-07269321f38e/output/powerpc64le-linux-gnu/bitcoin-07269321f38e-powerpc64le-linux-gnu.tar.gz
    18e52dd80a9c306d6aeb544acaa1f4ed560b6b92b5184764a05026d45451aa2e94  guix-build-07269321f38e/output/riscv64-linux-gnu/SHA256SUMS.part
    19864e0a16c485b4159cec3ee0a83b046f1b1c3bc821670011c5ac5cd09ddfb91f  guix-build-07269321f38e/output/riscv64-linux-gnu/bitcoin-07269321f38e-riscv64-linux-gnu-debug.tar.gz
    204a061172181322e7ad0cf06405bf74f4c8683eaba3a67ecfd46158cba7627f62  guix-build-07269321f38e/output/riscv64-linux-gnu/bitcoin-07269321f38e-riscv64-linux-gnu.tar.gz
    21876d82251853205420dffe7237523fc6ee3d09f78bf74cc03dc71f548446f335  guix-build-07269321f38e/output/x86_64-apple-darwin/SHA256SUMS.part
    223f82b2e62c60eee68e7b8fc28e4792e069e3c2cd780ee2d67290ca422cdbc47c  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.dmg
    234ccdd4c410cac9d627e54ce83ee4816608681735da3cb93c60c5eb70ca86337a  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx-unsigned.tar.gz
    242179d36b2f60e28c15262d4e51f27465b5ae077f60e550345e125683ca611066  guix-build-07269321f38e/output/x86_64-apple-darwin/bitcoin-07269321f38e-osx64.tar.gz
    25b377e72fe84b6a982b8d414d60c85e6319523dff50dc852a0ba907f6d850ddd0  guix-build-07269321f38e/output/x86_64-linux-gnu/SHA256SUMS.part
    268547e2f582ce05ae6a6224793b64efb2eb63f2816bf0bed5d53fcc4786274597  guix-build-07269321f38e/output/x86_64-linux-gnu/bitcoin-07269321f38e-x86_64-linux-gnu-debug.tar.gz
    2783b64805aa39f31a6fa4c2ed41e029c3be084e6dea06b90fac1ebca5c95bce29  guix-build-07269321f38e/output/x86_64-linux-gnu/bitcoin-07269321f38e-x86_64-linux-gnu.tar.gz
    
  344. hebasto commented at 2:49 pm on February 3, 2022: member

    ACK 07269321f38e46e9e02f16d7cd135ea90692638d

    Agree with @MarcoFalke’s comment.

  345. MarcoFalke merged this on Feb 3, 2022
  346. MarcoFalke closed this on Feb 3, 2022

  347. in src/wallet/bdb.cpp:624 in 41d7166c8a outdated
    620@@ -620,12 +621,12 @@ bool BerkeleyDatabase::Backup(const std::string& strDest) const
    621                     pathDest /= fs::PathFromString(strFile);
    622 
    623                 try {
    624-                    if (fs::equivalent(pathSrc, pathDest)) {
    625+                    if (fs::exists(pathDest) && fs::equivalent(pathSrc, pathDest)) {
    


    ryanofsky commented at 3:04 pm on February 3, 2022:

    In commit “build: remove boost::filesystem usage” (b87f9c5edf3895df9650131fcf8551c3ad1d7301)

    Note: this change was needed because fs::equivalent was throwing an exception if the path didn’t exist. Earlier discussion was #20744 (comment)

  348. in src/wallet/load.cpp:34 in 41d7166c8a outdated
    28@@ -27,9 +29,9 @@ bool VerifyWallets(WalletContext& context)
    29 
    30     if (args.IsArgSet("-walletdir")) {
    31         fs::path wallet_dir = fs::PathFromString(args.GetArg("-walletdir", ""));
    32-        boost::system::error_code error;
    33+        std::error_code error;
    34         // The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
    35-        fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error).remove_trailing_separator();
    36+        fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
    


    ryanofsky commented at 3:13 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    Note: std canonical function already strips trailing slashes, so this should not be a change in behavior

  349. in src/wallet/test/init_tests.cpp:77 in 41d7166c8a outdated
    72@@ -73,6 +73,8 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
    73     BOOST_CHECK_EQUAL(walletdir, expected_path);
    74 }
    75 
    76+#ifndef WIN32
    77+// Windows does not consider "datadir/wallets//" to be a valid directory path.
    


    ryanofsky commented at 3:24 pm on February 3, 2022:

    In commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247)

    What’s the behavior if you use this path on windows? I don’t think we want bitcoins’s behavior undefined and untested in this case. It would be better for users and also clearer in the test code to check what the resulting behavior is on windows and decide if it is good or bad.

    Or best thing might be to add a StripRedundantLastElementsOfPath call in the -walletdir= parsing code like the one that was added to GetDataDir in this PR, so this test could go back to be enabled and working the same across platforms.


    MarcoFalke commented at 4:04 pm on February 3, 2022:
    I was assuming that this modifies gArgs, but given that the args is local, it should be fine, assuming that the argsmanager doesn’t write to disk by itself.
  350. ryanofsky commented at 3:35 pm on February 3, 2022: member

    Partial code review ACK for commit “refactor: replace boost::filesystem with std::filesystem” (41d7166c8a598b604aad6c6b1d88ad46e23be247). I looked at this commit in detail, just not the other commits.

    Overall I think this is good, but there is some dodginess going on with trailing / characters in paths, that is showing up in comments here about tests on windows, but could indicate unintended changes in behavior that cause bugs on other platforms. Windows complains more about extra / characters in paths but that doesn’t mean extra / characters don’t break things on other platforms, too. For example if there are string comparisons that no longer return true because of extra slashes.

  351. ryanofsky referenced this in commit 8287489e7c on Feb 3, 2022
  352. ryanofsky referenced this in commit 3278e64a22 on Feb 3, 2022
  353. sidhujag referenced this in commit 5ebae3655f on Feb 3, 2022
  354. rebroad referenced this in commit b5656d9925 on Feb 3, 2022
  355. rebroad referenced this in commit 5bc3ee2cd6 on Feb 3, 2022
  356. hebasto commented at 9:12 pm on February 3, 2022: member

    Tested 0726932 on Ubuntu Bionic 18.04.

    The third commit b87f9c5 compiles ok, but the last commit fails:

    Fixed in #24254.

  357. fanquake deleted the branch on Feb 3, 2022
  358. MarcoFalke removed the label DrahtBot Guix build requested on Feb 4, 2022
  359. ryanofsky referenced this in commit 80cd64e842 on Feb 4, 2022
  360. ryanofsky referenced this in commit d216bc8d76 on Feb 4, 2022
  361. ryanofsky referenced this in commit 824e1ffa9f on Feb 4, 2022
  362. fanquake referenced this in commit 372cb6c186 on Feb 5, 2022
  363. fanquake referenced this in commit 1e7564eca8 on Feb 5, 2022
  364. sidhujag referenced this in commit a603a53ec8 on Feb 6, 2022
  365. sidhujag referenced this in commit 6c7e78fb94 on Feb 6, 2022
  366. sidhujag referenced this in commit 44d64d6802 on Feb 6, 2022
  367. domob1812 referenced this in commit be1e29ad4a on Feb 7, 2022
  368. MarcoFalke commented at 2:09 pm on February 7, 2022: member
  369. DrahtBot commented at 9:57 am on February 8, 2022: member

    Guix builds

    File commit 133f73e86bd7c3114263500be2fb5090dd76b4bc(master) commit c22ce78ce460aa5ae6870c0f6ec3f83182506a29(master and this pull)
    SHA256SUMS.part 4d29ebeb3309d60d... fe3150bbd0109d5f...
    *-aarch64-linux-gnu-debug.tar.gz c29ba0d0426063e8... e16ef933ef09c924...
    *-aarch64-linux-gnu.tar.gz e52c846b1841b3eb... 89b610a00c36b994...
    *-arm-linux-gnueabihf-debug.tar.gz 5d3f9731cf88da5b... 4c1e672b25015b27...
    *-arm-linux-gnueabihf.tar.gz 282b33b13dd1f8a0... 16dfc5343616a8f2...
    *-arm64-apple-darwin.tar.gz 3f0dba0a6549c410... 68cf545be72ba21c...
    *-osx-unsigned.dmg 6692809452b6cb62... 1d7e80f446d77db4...
    *-osx-unsigned.tar.gz 4366f453672f800d... 135c65dd5f337523...
    *-osx64.tar.gz 5387d0cdc36be37a... aa75f3413a4a724d...
    *-powerpc64-linux-gnu-debug.tar.gz 1ed57908059941ef... efa6d04faf2798ae...
    *-powerpc64-linux-gnu.tar.gz 21079e1bae0f459b... adcc9fe3a4e926d6...
    *-powerpc64le-linux-gnu-debug.tar.gz 6b441c519f2d3185... d6f4c9fb1386b4e5...
    *-powerpc64le-linux-gnu.tar.gz 132f95573d0fd005... affab9079ecc51be...
    *-riscv64-linux-gnu-debug.tar.gz 3c5e1f8e3d9aa92a... 4acf9cee4026d4a8...
    *-riscv64-linux-gnu.tar.gz b17efbca76425fc5... 0a8151ca3ddd5261...
    *-x86_64-linux-gnu-debug.tar.gz 9f61cd7fca8d6425... 19538169ad68c373...
    *-x86_64-linux-gnu.tar.gz 323dc8d7d0aa8290... 4642e4b995756947...
    *.tar.gz 5887839fbd29cd1c... a83d8979a6d86f22...
    guix_build.log 53868781dafe6675... 6a54af53a5cc64da...
    guix_build.log.diff 3887c19da2411792...
  370. fanquake referenced this in commit 8c0f02c69d on Feb 9, 2022
  371. sidhujag referenced this in commit 5081a72c21 on Feb 10, 2022
  372. sh15h4nk referenced this in commit 70cd589227 on Feb 13, 2022
  373. sh15h4nk referenced this in commit 8fe2ebdb21 on Feb 13, 2022
  374. sh15h4nk referenced this in commit cba847dad0 on Feb 13, 2022
  375. sh15h4nk referenced this in commit 2cad1f9707 on Feb 13, 2022
  376. sh15h4nk referenced this in commit c969780de8 on Feb 13, 2022
  377. rebroad referenced this in commit d1e85e1242 on Feb 15, 2022
  378. rebroad referenced this in commit f0dc0ae2b1 on Feb 15, 2022
  379. rebroad referenced this in commit b6acf6f6e6 on Feb 15, 2022
  380. janus referenced this in commit 23980dd6fd on Jul 24, 2022
  381. Fabcien referenced this in commit 9a1aa20252 on Sep 14, 2022
  382. dekm referenced this in commit fe2293e6c1 on Oct 27, 2022
  383. backpacker69 referenced this in commit 7910bf7c9b on Jan 18, 2023
  384. Fabcien referenced this in commit 0804f1a95b on Feb 27, 2023
  385. Fabcien referenced this in commit a60d80ab6a on Apr 21, 2023
  386. PastaPastaPasta referenced this in commit 525e2d8159 on May 10, 2023
  387. fanquake referenced this in commit a94ae1c5b4 on May 29, 2023
  388. DrahtBot locked this on Jun 17, 2023

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 12:12 UTC

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