p2p: Avoid InitError when downgrading peers.dat #24201

pull junderw wants to merge 1 commits into bitcoin:master from junderw:fixes/24188 changing 4 files +24 −10
  1. junderw commented at 1:04 pm on January 29, 2022: contributor

    fixes #24188 (also see #22762 (comment)) When downgrading, a peers.dat with a future version that has a minimum required version larger than the downgraded Bitcoin Core version would cause an InitError.

    This commit changes this behavior to overwrite the existing peers.dat with a new empty one.

  2. junderw commented at 1:42 pm on January 29, 2022: contributor

    Part of the reason why I am using strncmp is because AddrMan (AddrManImpl) -> Unserialize might be called somewhere else, so I didn’t want to touch it.

    I should probably re-work AddrManImpl to use a new exception class that wraps around std::ios_base::failure and only throw exception in the case of version mismatch… but I wanted to get feedback first.

  3. MarcoFalke commented at 1:51 pm on January 29, 2022: member
    Yeah, I think it should be thrown directly where the version is read
  4. DrahtBot added the label P2P on Jan 29, 2022
  5. junderw commented at 11:36 pm on January 29, 2022: contributor

    Fixed.

    Also, 2 jobs on the first commit’s CI have been running for 10 hours… is this caused by my strncmp?

  6. junderw commented at 11:18 pm on January 30, 2022: contributor
    On second look, I wonder if we should also LogPrintf the e.what() right before we LogPrintf "Creating new peers.dat..."?
  7. kallewoof commented at 6:05 am on January 31, 2022: member
    ACK 96c9d9c7efa13128df74cebf8dda7d1e5db1f9c6
  8. luke-jr changes_requested
  9. luke-jr commented at 7:57 am on February 6, 2022: member
    IMO should be squashed
  10. junderw force-pushed on Feb 6, 2022
  11. junderw commented at 10:45 am on February 6, 2022: contributor
    Squashed.
  12. in src/addrdb.cpp:207 in 2948297f4f outdated
    195@@ -196,6 +196,11 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
    196         addrman = std::make_unique<AddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    197         LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    198         DumpPeerAddresses(args, *addrman);
    199+    } catch (const InvalidAddrManVersionError&) {
    200+        // Addrman can be in an inconsistent state after failure, reset it
    201+        addrman = std::make_unique<AddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    202+        LogPrintf("Creating new peers.dat because the file version was not compatible (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    203+        DumpPeerAddresses(args, *addrman);
    


    luke-jr commented at 7:45 pm on February 6, 2022:

    Would be nice to deduplicate the common code here somehow.

    Maybe just a single common catch of std::exception, with if(DbNotFoundError) else if (InvalidAddrManVersionError) else return then the common re-init logic?


    junderw commented at 10:57 pm on February 6, 2022:
    👍 I will do a follow up once this is merged.
  13. in src/addrdb.cpp:202 in 2948297f4f outdated
    195@@ -196,6 +196,11 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
    196         addrman = std::make_unique<AddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    197         LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    198         DumpPeerAddresses(args, *addrman);
    199+    } catch (const InvalidAddrManVersionError&) {
    200+        // Addrman can be in an inconsistent state after failure, reset it
    201+        addrman = std::make_unique<AddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    202+        LogPrintf("Creating new peers.dat because the file version was not compatible (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    


    luke-jr commented at 7:47 pm on February 6, 2022:
    I wonder if the old file should be backed up first.

    junderw commented at 10:56 pm on February 6, 2022:
    I am not sure if that would be useful. Anyone who cares about which peers they connect to is probably managing a conf file filled with add peer directives.

    unknown commented at 11:13 pm on February 6, 2022:
    Agree with luke-jr

    junderw commented at 11:32 pm on February 6, 2022:

    I just saw your issue on knots.

    I will make a backup at peers.dat.bak.


    junderw commented at 3:01 am on February 7, 2022:
    The behavior has changed to back up to .bak file. Please let me know what you think of the commit before I squash it.
  14. luke-jr approved
  15. luke-jr commented at 7:47 pm on February 6, 2022: member
    utACK, w/ some thoughts for improvement (can be followups)
  16. in src/addrdb.cpp:201 in f2125c1c6a outdated
    196@@ -197,9 +197,12 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
    197         LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    198         DumpPeerAddresses(args, *addrman);
    199     } catch (const InvalidAddrManVersionError&) {
    200+        if (!RenameOver(path_addr, (fs::path)path_addr + ".bak")) {
    201+            throw std::exception();
    


    kallewoof commented at 4:50 am on February 7, 2022:
    0throw std::runtime_error{"Failed to rename invalid peer.dat file. Please move or delete it and try again."};
    

    junderw commented at 5:28 am on February 7, 2022:
    Doesn’t this error get caught by the catch below (which catches exception)?

    kallewoof commented at 6:18 am on February 7, 2022:
    Ah yeah didn’t realize this was caught later, I thought you just hard-crashed. Either way, you do want it to be caught and handled below, but the wording here is a bit redundant. Maybe just “Failed to move invalid peer.dat file aside.”?

    junderw commented at 6:51 am on February 7, 2022:
    Actually, it looks like throwing here bypasses the later catch.

    junderw commented at 6:52 am on February 7, 2022:
    Maybe I should refactor the other comment from Luke to make things cleaner.
  17. in test/functional/feature_addrman.py:73 in 772c9ba8cc outdated
    67@@ -68,17 +68,16 @@ def run_test(self):
    68             self.start_node(0, extra_args=["-checkaddrman=1"])
    69         assert_equal(self.nodes[0].getnodeaddresses(), [])
    70 
    71-        self.log.info("Check that addrman from future cannot be read")
    72+        self.log.info("Check that addrman from future is overwritten with new addrman")
    73         self.stop_node(0)
    74         write_addrman(peers_dat, lowest_compatible=111)
    


    unknown commented at 4:26 am on February 8, 2022:
    0write_addrman(peers_dat, lowest_compatible=111)
    

    Is it possible to do this using some hidden RPC?


    junderw commented at 7:18 am on February 8, 2022:
    Nope. This is a python function that literally just writes a dummy (but valid) peers.dat file to disk.
  18. DrahtBot commented at 5:21 pm on February 11, 2022: 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:

    • #24312 (addrman: Log too low compat value by MarcoFalke)

    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.

  19. in src/addrdb.cpp:202 in 772c9ba8cc outdated
    195@@ -196,6 +196,15 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
    196         addrman = std::make_unique<AddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    197         LogPrintf("Creating peers.dat because the file was not found (%s)\n", fs::quoted(fs::PathToString(path_addr)));
    198         DumpPeerAddresses(args, *addrman);
    199+    } catch (const InvalidAddrManVersionError&) {
    200+        if (!RenameOver(path_addr, (fs::path)path_addr + ".bak")) {
    201+            addrman = nullptr;
    202+            return strprintf(_("Failed to rename invalid peer.dat file. Please move or delete it and try again."));
    


    luke-jr commented at 1:36 am on February 20, 2022:
    peers.dat
  20. junderw renamed this:
    p2p: Avoid InitError when downgrading peers.dat
    WIP: p2p: Avoid InitError when downgrading peers.dat
    on Feb 20, 2022
  21. MarcoFalke added this to the milestone 23.0 on Feb 21, 2022
  22. MarcoFalke commented at 1:25 pm on February 21, 2022: member
    Assigned 23.0
  23. michaelfolkson commented at 7:24 pm on February 24, 2022: contributor
    @junderw: Can you explain why you made this WIP? One of multiple considerations for whether it should be included in the 23.0 milestone or not.
  24. junderw renamed this:
    WIP: p2p: Avoid InitError when downgrading peers.dat
    p2p: Avoid InitError when downgrading peers.dat
    on Feb 24, 2022
  25. junderw commented at 10:03 pm on February 24, 2022: contributor

    Sorry, I misunderstood. I made it WIP because I thought I still hadn’t finished all the outstanding issues with the PR.

    After reviewing my own commit I understand I was just confused.

    There’s a spelling error I’ll fix right now.

  26. unknown approved
  27. unknown commented at 10:06 pm on February 24, 2022: none

    tACK https://github.com/bitcoin/bitcoin/pull/24201/commits/772c9ba8ccfa7247042be10771cca3c8de7e8568

    nit:

    1. Not sure about squashing of some commits or the order and type
    2. Suggestion by @luke-jr still not addressed to change peer to peers
  28. junderw commented at 11:43 pm on February 24, 2022: contributor
    Unrelated test failed for some reason.
  29. ghost commented at 11:52 pm on February 24, 2022: none

    Unrelated test failed for some reason.

    I don’t think that’s an issue

    Maybe you can follow 1 or 2 or both:

    1. Squash commits according to docs
    2. Have 2 commits:
      01st commit: net (src/addrman.h , src/addrman.cpp and src/addrdb.cpp)
      
      02nd commit: test (test/functional/feature_addrman.py)
      
  30. p2p: Avoid InitError when downgrading peers.dat
    fixes #24188
    When downgrading, a peers.dat with a future version that has a minimum
    required version larger than the downgraded version would cause an InitError.
    
    This commit changes this behavior to overwrite the existing peers.dat with
    a new empty one, while creating a backup in peers.dat.bak.
    d41ed32153
  31. junderw force-pushed on Feb 25, 2022
  32. junderw commented at 0:55 am on February 25, 2022: contributor
    Squashed all commits into one.
  33. unknown approved
  34. kallewoof commented at 4:16 am on February 25, 2022: member
    reACK d41ed3215355582879c8eb6c99c2da33852f6cb1
  35. MarcoFalke merged this on Feb 25, 2022
  36. MarcoFalke closed this on Feb 25, 2022

  37. michaelfolkson commented at 11:06 am on February 25, 2022: contributor
    Sorry for the confusion @junderw :) Great to see this has been merged. Thanks!
  38. junderw deleted the branch on Feb 25, 2022
  39. sidhujag referenced this in commit 7da3620dbe on Feb 25, 2022
  40. Fabcien referenced this in commit 9c011e33ad on Oct 21, 2022
  41. DrahtBot locked this on Feb 25, 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: 2025-01-02 15:12 UTC

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