Raise InitError when peers.dat is invalid or corrupted #22762

pull MarcoFalke wants to merge 3 commits into bitcoin:master from MarcoFalke:2108-InitErrorAddrmanCorrupt changing 6 files +88 −67
  1. MarcoFalke commented at 12:41 pm on August 21, 2021: member

    peers.dat is silently erased when it can not be parsed or when it appears corrupted. Fix that by notifying the user. This might help in the following examples:

    • The user provided the database, but picked the wrong one.
    • A future version of Bitcoin Core wrote the file and it can’t be read.
    • The file was corrupted by a logic bug in Bitcoin Core.
    • The file was corrupted by a disk failure.
  2. DrahtBot added the label GUI on Aug 21, 2021
  3. DrahtBot added the label P2P on Aug 21, 2021
  4. MarcoFalke removed the label GUI on Aug 21, 2021
  5. MarcoFalke force-pushed on Aug 21, 2021
  6. MarcoFalke force-pushed on Aug 21, 2021
  7. DrahtBot commented at 9:56 pm on August 21, 2021: 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:

    • #22937 (refactor: Add fs::PathToString, fs::PathFromString, u8string, u8path functions by ryanofsky)
    • #22831 (test, bugfix: addrman tried table corruption on restart with asmap by jonatack)

    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.

  8. in src/addrdb.cpp:184 in fa50c25b1a outdated
    244-    return DeserializeFileDB(pathAddr, addr, CLIENT_VERSION);
    245+    DeserializeDB(ssPeers, addr, false);
    246 }
    247 
    248-bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
    249+std::optional<bilingual_str> LoadAddrman(const ArgsManager& args, std::unique_ptr<CAddrMan>& addrman)
    


    vasild commented at 11:53 am on August 24, 2021:

    I would expect LoadAddrman() to return, eh… addrman, no? Like Foo x = LoadFoo();. Consider this (or ignore it):

    0std::unique_ptr<CAddrMan> LoadAddrman(const ArgsManager& args, bilingual_str& error);
    1
    2bilingual_str error;
    3node.addrman = LoadAddrman(args, error);
    4if (!node.addrman) {
    5    return InitError(error);
    6}
    

    MarcoFalke commented at 8:53 am on August 26, 2021:
    This would make the code more verbose. In general I rather standardize error handling how it is done in rust, which the current code is closer to than yours, I think.
  9. in src/addrdb.cpp:254 in fa50c25b1a outdated
    259+        DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
    260+        LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman->size(), GetTimeMillis() - nStart);
    261+    } catch (const DbNotFoundError&) {
    262+        // Addrman can be in an inconsistent state after failure, reset it
    263+        addrman = std::make_unique<CAddrMan>(/* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    264+        LogPrintf("Recreating peers.dat because it was not found\n");
    


    vasild commented at 12:01 pm on August 24, 2021:

    nit: there is no re-creating if the file is missing:

    0        LogPrintf("Creating peers.dat because it was not found\n");
    

    or just “Creating peers.dat” or “peers.dat not found, creating an empty one”


    MarcoFalke commented at 9:03 am on August 26, 2021:
    Thanks, fixed
  10. in src/addrdb.cpp:174 in fa50c25b1a outdated
    197     FILE* file = fsbridge::fopen(path, "rb");
    198     CAutoFile filein(file, SER_DISK, version);
    199     if (filein.IsNull()) {
    200-        LogPrintf("Missing or invalid file %s\n", path.string());
    201-        return false;
    202+        throw DbNotFoundError{""};
    


    vasild commented at 12:07 pm on August 24, 2021:

    The string argument is excessive. Maybe inherit DbNotFoundError from std::exception and use throw DbNotFoundError;? Or, I guess, the proper C++ way to do that is:

    0try {
    1    throw std::system_error(std::make_error_code(std::errc::no_such_file_or_directory));
    2} catch (const std::exception& e) {
    3    auto se = dynamic_cast<const std::system_error*>(&e);
    4    if (se != nullptr && se->code() == std::errc::no_such_file_or_directory) {
    5        std::cout << "no peers.dat" << std::endl;
    6    } else {
    7        std::cout << e.what() << std::endl;
    8    }
    9}
    

    MarcoFalke commented at 9:03 am on August 26, 2021:
    Thanks, removed "".
  11. ghost commented at 5:18 pm on August 24, 2021: none
    Concept ACK
  12. MarcoFalke force-pushed on Aug 26, 2021
  13. MarcoFalke commented at 9:04 am on August 26, 2021: member
    force pushed to address review comments
  14. vasild approved
  15. vasild commented at 9:25 am on August 27, 2021: member
    ACK fa1704a2f49eaedf5788d82294485f3a8e17a6c8
  16. in src/addrdb.cpp:118 in fa1704a2f4 outdated
    197     FILE* file = fsbridge::fopen(path, "rb");
    198     CAutoFile filein(file, SER_DISK, version);
    199     if (filein.IsNull()) {
    200-        LogPrintf("Missing or invalid file %s\n", path.string());
    201-        return false;
    202+        throw DbNotFoundError{};
    


    vasild commented at 9:27 am on August 27, 2021:
    nit: {} is not necessary

    MarcoFalke commented at 3:58 pm on September 1, 2021:

    Not for me:

    0addrdb.cpp:174:15: error: 'DbNotFoundError' does not refer to a value
    1        throw DbNotFoundError;
    2              ^
    

    vasild commented at 5:58 am on September 2, 2021:
    ah, oh, yes of course, sorry for the noise
  17. DrahtBot added the label Needs rebase on Sep 1, 2021
  18. MarcoFalke force-pushed on Sep 1, 2021
  19. MarcoFalke force-pushed on Sep 1, 2021
  20. DrahtBot removed the label Needs rebase on Sep 1, 2021
  21. vasild approved
  22. vasild commented at 5:59 am on September 2, 2021: member
    ACK faff4fd4e00621a02554233effa8f144990f3dd8
  23. jonatack commented at 10:40 am on September 3, 2021: member

    Concept ACK.

    Like other open pulls to change or fix addrman behavior, it might be good to have functional/regression test coverage in place first.

  24. DrahtBot added the label Needs rebase on Sep 6, 2021
  25. MarcoFalke force-pushed on Sep 6, 2021
  26. vasild approved
  27. vasild commented at 10:35 am on September 6, 2021: member
    ACK b4cc1c52e103f6fc3969daefc1ba11ac4af4d606
  28. MarcoFalke removed the label Needs rebase on Sep 6, 2021
  29. DrahtBot added the label Needs rebase on Sep 6, 2021
  30. MarcoFalke force-pushed on Sep 6, 2021
  31. DrahtBot removed the label Needs rebase on Sep 6, 2021
  32. vasild approved
  33. vasild commented at 3:52 pm on September 6, 2021: member
    ACK faa75278d076874194073a6cb3974f45de051ffc
  34. in src/addrman.h:20 in faa75278d0 outdated
    16 #include <random.h>
    17 #include <streams.h>
    18 #include <sync.h>
    19 #include <timedata.h>
    20 #include <tinyformat.h>
    21-#include <util/system.h>
    


    jonatack commented at 4:45 pm on September 6, 2021:
    fa9aed72 while fixing the addrman includes may as well do these too: #22740 (comment)

    MarcoFalke commented at 9:06 am on September 7, 2021:
    Thanks, done
  35. in src/test/addrman_tests.cpp:1046 in faa75278d0 outdated
    1042     CDataStream ssPeers2 = AddrmanToStream(addrmanUncorrupted);
    1043 
    1044     CAddrMan addrman2(/* asmap */ std::vector<bool>(), /* deterministic */ false, /* consistency_check_ratio */ 100);
    1045     BOOST_CHECK(addrman2.size() == 0);
    1046-    BOOST_CHECK(CAddrDB::Read(addrman2, ssPeers2));
    1047+    ReadFromStream(addrman2, ssPeers2);
    


    jonatack commented at 4:57 pm on September 6, 2021:

    fa63ebb21 CAddrDB removed in this commit; update these references

     0--- a/src/test/addrman_tests.cpp
     1+++ b/src/test/addrman_tests.cpp
     2@@ -1002,7 +1002,7 @@ BOOST_AUTO_TEST_CASE(addrman_evictionworks)
     3     BOOST_CHECK(addrman.SelectTriedCollision().ToString() == "[::]:0");
     4 }
     5 
     6-BOOST_AUTO_TEST_CASE(caddrdb_read)
     7+BOOST_AUTO_TEST_CASE(load_addrman)
     8 {
     9     CAddrManUncorrupted addrmanUncorrupted;
    10 
    11@@ -1047,7 +1047,7 @@ BOOST_AUTO_TEST_CASE(caddrdb_read)
    12 }
    13 
    14 
    15-BOOST_AUTO_TEST_CASE(caddrdb_read_corrupted)
    16+BOOST_AUTO_TEST_CASE(load_corrupted_addrman)
    17 {
    18     CAddrManCorrupted addrmanCorrupted;
    

    MarcoFalke commented at 9:07 am on September 7, 2021:
    Thanks, done
  36. in src/addrdb.cpp:202 in faa75278d0 outdated
    207+        addrman = std::make_unique<CAddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    208+        LogPrintf("Creating peers.dat because it was not found\n");
    209+        DumpPeerAddresses(args, *addrman);
    210+    } catch (const std::exception& e) {
    211+        addrman = nullptr;
    212+        return strprintf(_("Addrman invalid or corrupt (%s). If you believe this is a bug, please report it to %s. As a workaround you can move the database (%s) out of the way (rename, move, or delete) to use a fresh one on the next start."),
    


    jonatack commented at 5:29 pm on September 6, 2021:

    faa75278d076874194073a6cb397 suggestions

    0        return strprintf(_("Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) and bitcoind will create a new one on the next start."),
    

    MarcoFalke commented at 9:07 am on September 7, 2021:
    Thanks, done
  37. in src/addrdb.cpp:198 in faa75278d0 outdated
    203+        DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
    204+        LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman->size(), GetTimeMillis() - nStart);
    205+    } catch (const DbNotFoundError&) {
    206+        // Addrman can be in an inconsistent state after failure, reset it
    207+        addrman = std::make_unique<CAddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    208+        LogPrintf("Creating peers.dat because it was not found\n");
    


    jonatack commented at 5:37 pm on September 6, 2021:
    faa75278d076874194073a6cb3974f45de051ffc Perhaps also log to the user the location where the file was expected to be (as is currently the case).

    MarcoFalke commented at 9:07 am on September 7, 2021:
    Good catch, done
  38. jonatack commented at 5:38 pm on September 6, 2021: member

    Tested/reviewed approach ACK fabe5b5838812e58cc.

    Cherry-picked #22831 onto this branch and the test coverage passed after the following changes; can update that PR if this is merged first:

     0@@ -106,7 +106,7 @@ class AddrmanAsmapTest(BitcoinTestFramework):
     1         self.log.info('Test bitcoind with missing peers.dat and addrman checks')
     2         self.stop_node(0)
     3         os.remove(os.path.join(self.datadir, 'peers.dat'))
     4-        with self.node.assert_debug_log([f'Missing or invalid file {self.datadir}/peers.dat', 'Recreating peers.dat']):
     5+        with self.node.assert_debug_log(['Creating peers.dat because it was not found']):
     6             self.start_node(0, ['-checkaddrman=1'])
     7             self.node.getnodeaddresses()
     8 
     9@@ -114,9 +114,12 @@ class AddrmanAsmapTest(BitcoinTestFramework):
    10         self.log.info('Test bitcoind with peers.dat having invalid network magic and addrman checks')
    11         self.stop_node(0)
    12         shutil.copyfile(self.asmap_raw, os.path.join(self.datadir, 'peers.dat'))
    13-        with self.node.assert_debug_log(['Invalid network magic number', 'Recreating peers.dat']):
    14-            self.start_node(0, ['-checkaddrman=1'])
    15-            self.node.getnodeaddresses()
    16+        msg = (
    17+            'Error: Addrman invalid or corrupt (Invalid network magic number). If you believe this is a bug, please '
    18+            'report it to https://github.com/bitcoin/bitcoin/issues. As a workaround you can move the database '
    19+            f'("{self.datadir}/peers.dat") out of the way (rename, move, or delete) to use a fresh one on the next start.'
    20+            )
    21+        self.node.assert_start_raises_init_error(extra_args=['-checkaddrman=1'], expected_msg=msg)
    22 
    23     def run_test(self):
    24         self.node = self.nodes[0]
    
  39. MarcoFalke force-pushed on Sep 7, 2021
  40. MarcoFalke force-pushed on Sep 7, 2021
  41. vasild approved
  42. vasild commented at 10:12 am on September 7, 2021: member
    ACK fa7003f949f21a0ba81388caff1ff986d8b43eed
  43. MarcoFalke closed this on Sep 7, 2021

  44. MarcoFalke reopened this on Sep 7, 2021

  45. in src/addrdb.h:50 in fa7003f949 outdated
    46@@ -52,6 +47,9 @@ class CBanDB
    47     bool Read(banmap_t& banSet);
    48 };
    49 
    50+/** Returns an error string on failure */
    


    jonatack commented at 2:26 pm on September 7, 2021:

    fa035c1 suggestion if you retouch

    0/** Load addresses from peers.dat into addrman. Returns an error string on failure */
    

    MarcoFalke commented at 4:02 pm on September 7, 2021:
    I don’t think other modules care much about the exact file name, so I didn’t mention it, as it is self-documented in the addrdb implementation file (cpp) already. And the “Load addresses” part should already be clear from the function name.
  46. in src/init.cpp:1206 in fa7003f949 outdated
    1199@@ -1200,20 +1200,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
    1200             LogPrintf("Using /16 prefix for IP bucketing\n");
    1201         }
    1202 
    1203-        auto check_addrman = std::clamp<int32_t>(args.GetArg("-checkaddrman", DEFAULT_ADDRMAN_CONSISTENCY_CHECKS), 0, 1000000);
    1204-        node.addrman = std::make_unique<CAddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    1205-
    1206-        // Load addresses from peers.dat
    


    jonatack commented at 2:27 pm on September 7, 2021:
    fa035c1 perhaps keep this comment

    MarcoFalke commented at 4:00 pm on September 7, 2021:
    I don’t think it is important to document the file name in init.cpp, so I removed it
  47. jonatack commented at 3:54 pm on September 7, 2021: member

    ACK fa7003f949f21a0ba81388caff1ff986d8b43eed review / debug build clean on each commit, verified the test coverage of #22831 passes on this branch with the following changes

     0--- a/test/functional/feature_addrman_asmap.py
     1+++ b/test/functional/feature_addrman_asmap.py
     2@@ -106,17 +106,21 @@ class AddrmanAsmapTest(BitcoinTestFramework):
     3         self.log.info('Test bitcoind with missing peers.dat and addrman checks')
     4         self.stop_node(0)
     5         os.remove(os.path.join(self.datadir, 'peers.dat'))
     6-        with self.node.assert_debug_log([f'Missing or invalid file {self.datadir}/peers.dat', 'Recreating peers.dat']):
     7+        msg = f'Creating peers.dat because the file was not found ("{self.datadir}/peers.dat")'
     8+        with self.node.assert_debug_log(expected_msgs=[msg]):
     9             self.start_node(0, ['-checkaddrman=1'])
    10 
    11     def test_peers_dat_with_invalid_network_magic(self):
    12         self.log.info('Test bitcoind with peers.dat having invalid network magic and addrman checks')
    13         self.stop_node(0)
    14         shutil.copyfile(self.asmap_raw, os.path.join(self.datadir, 'peers.dat'))
    15-        with self.node.assert_debug_log(['Invalid network magic number', 'Recreating peers.dat']):
    16-            self.start_node(0, ['-checkaddrman=1'])
    17-            self.node.getnodeaddresses()
    18+        msg = (
    19+            'Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please '
    20+            'report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file '
    21+            f'("{self.datadir}/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.'
    22+            )
    23+        self.node.assert_start_raises_init_error(extra_args=['-checkaddrman=1'], expected_msg=msg)
    
  48. ghost commented at 7:05 pm on September 7, 2021: none

    Tested on Pop!_OS and everything works as expected and mentioned in PR description.

    Master Branch:

    peers.dat is replaced with a new file if it is corrupt or other issues.

    image

    image

    PR Branch:

    A. Corrupt peers.dat file

    1. Open peers.dat add random characters in beginning and save.
    2. Run bitcoind
    02021-09-07T18:05:46Z init message: Loading P2P addresses…
    12021-09-07T18:05:46Z Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file ("/home/prayank/.bitcoin/regtest/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.
    2Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file ("/home/prayank/.bitcoin/regtest/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.
    32021-09-07T18:05:46Z Shutdown: In progress...
    

    :warning: Not sure why same error printed twice in terminal running bitcoind. I see only one error message in debug.log:

    02021-09-07T18:05:46Z init message: Loading P2P addresses…
    12021-09-07T18:05:46Z Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file ("/home/prayank/.bitcoin/regtest/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.
    22021-09-07T18:05:46Z Shutdown: In progress...
    

    B. peers.dat from testnet used in regtest

    1. Delete regtest/peers.dat and copy testnet3/peers.dat in regtest/
    2. Run bitcoind
    02021-09-07T18:14:33Z init message: Loading P2P addresses…
    12021-09-07T18:14:33Z Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file ("/home/prayank/.bitcoin/regtest/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.
    2Error: Invalid or corrupt peers.dat (Invalid network magic number). If you believe this is a bug, please report it to https://github.com/bitcoin/bitcoin/issues. As a workaround, you can move the file ("/home/prayank/.bitcoin/regtest/peers.dat") out of the way (rename, move, or delete) to have a new one created on the next start.
    32021-09-07T18:14:33Z Shutdown: In progress...
    

    Fix the issue by following the things mentioned in error: Delete peers.dat and restart bitcoind. No issues. :white_check_mark:

  49. MarcoFalke referenced this in commit 896649996b on Sep 9, 2021
  50. Move LoadAddrman from init to addrdb
    Init should only concern itself with the initialization order, not the
    detailed initialization logic of every module.
    
    Also, inlining logic into a method that is ~800 lines of code, makes it
    impossible to unit test on its own.
    fa5aeec80c
  51. Inline ReadPeerAddresses
    No need to have a function that is only called in one place
    fa4e2ccfd8
  52. MarcoFalke force-pushed on Sep 9, 2021
  53. Raise InitError when peers.dat is invalid or corrupted fa55c3dc1b
  54. MarcoFalke force-pushed on Sep 9, 2021
  55. MarcoFalke commented at 7:25 am on September 9, 2021: member
    Rebased (only change is in tests)
  56. jonatack commented at 8:44 am on September 9, 2021: member
    Code review re-ACK fa55c3dc1b4bbdc6a53bd11fa6c0b2ec6bbb64ae per git range-diff eb1f570 fa59c6d fa55c3 and verified the new tests fail on master, except “Check mocked addrman is valid”, as expected
  57. in test/functional/feature_addrman.py:68 in fa55c3dc1b
    69-        assert_equal(self.nodes[0].getnodeaddresses(), [])
    70+        self.nodes[0].assert_start_raises_init_error(
    71+            expected_msg=init_error(
    72+                "Unsupported format of addrman database: 1. It is compatible with "
    73+                "formats >=111, but the maximum supported by this version of "
    74+                f"{self.config['environment']['PACKAGE_NAME']} is 3.: (.+)"
    


    vasild commented at 10:02 am on September 9, 2021:

    This is somewhat confusing or designates a corrupted file, not one from the future. How could the file be format=1 and only be compatible with formats larger than 111? If the above is changed as:

    0-write_addrman(peers_dat, lowest_compatible=111)
    1+write_addrman(peers_dat, format=115, lowest_compatible=111)
    

    it will be a bit more realistic.

    Feel free to ignore as out of the scope of this PR, given that a similar message is already in master.


    MarcoFalke commented at 10:58 am on September 9, 2021:

    Instead of “fixing” the test, I think rejecting formats that are less than lowest_compatible seems like a good sanity check. Though, this would be an unrelated fix in a separate pull:

     0diff --git a/src/addrman.cpp b/src/addrman.cpp
     1index 174b3a654c..bcffe64de3 100644
     2--- a/src/addrman.cpp
     3+++ b/src/addrman.cpp
     4@@ -243,7 +243,7 @@ void CAddrMan::Unserialize(Stream& s_)
     5     uint8_t compat;
     6     s >> compat;
     7     const uint8_t lowest_compatible = compat - INCOMPATIBILITY_BASE;
     8-    if (lowest_compatible > FILE_FORMAT) {
     9+    if (format < lowest_compatible || lowest_compatible > FILE_FORMAT) {
    10         throw std::ios_base::failure(strprintf(
    11             "Unsupported format of addrman database: %u. It is compatible with formats >=%u, "
    12             "but the maximum supported by this version of %s is %u.",
    

    vasild commented at 11:25 am on September 9, 2021:
    +1, maybe each condition deserves its own error message.
  58. vasild approved
  59. vasild commented at 10:03 am on September 9, 2021: member
    ACK fa55c3dc1b4bbdc6a53bd11fa6c0b2ec6bbb64ae
  60. ghost commented at 12:44 pm on September 9, 2021: none

    tACK https://github.com/bitcoin/bitcoin/commit/fa55c3dc1b4bbdc6a53bd11fa6c0b2ec6bbb64ae

    nit: Will be better if error message was printed only once #22762 (comment)

  61. MarcoFalke commented at 12:50 pm on September 9, 2021: member

    nit: Will be better if error message was printed only once #22762 (comment)

    InitErrors are printed to the debug log and stderr. I think it makes sense to print them to both instead of only one.

  62. MarcoFalke merged this on Sep 10, 2021
  63. MarcoFalke closed this on Sep 10, 2021

  64. MarcoFalke deleted the branch on Sep 10, 2021
  65. in src/addrdb.cpp:195 in fa55c3dc1b
    195+    const auto path_addr{args.GetDataDirNet() / "peers.dat"};
    196+    try {
    197+        DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
    198+        LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman->size(), GetTimeMillis() - nStart);
    199+    } catch (const DbNotFoundError&) {
    200+        // Addrman can be in an inconsistent state after failure, reset it
    


    MarcoFalke commented at 11:06 am on September 10, 2021:

    Just to clarify that, strictly, this isn’t needed. DbNotFoundError means that the file wasn’t found, so addrman shouldn’t be touched at all.

    Does anyone have opinions on whether to remove it or not?


    vasild commented at 11:34 am on September 10, 2021:
    But we need to distinguish somehow this from the other error case, so that we don’t signal an error to the caller in this case?

    MarcoFalke commented at 11:37 am on September 10, 2021:

    I meant recreating the addrman can be skipped, because it wasn’t touched. Saves two lines of code:

     0diff --git a/src/addrdb.cpp b/src/addrdb.cpp
     1index 1e73750ce3..a86f4c3789 100644
     2--- a/src/addrdb.cpp
     3+++ b/src/addrdb.cpp
     4@@ -192,8 +192,6 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
     5         DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
     6         LogPrintf("Loaded %i addresses from peers.dat  %dms\n", addrman->size(), GetTimeMillis() - nStart);
     7     } catch (const DbNotFoundError&) {
     8-        // Addrman can be in an inconsistent state after failure, reset it
     9-        addrman = std::make_unique<CAddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
    10         LogPrintf("Creating peers.dat because the file was not found (%s)\n", path_addr);
    11         DumpPeerAddresses(args, *addrman);
    12     } catch (const std::exception& e) {
    

    vasild commented at 12:01 pm on September 10, 2021:
    This would leave the unique_ptr empty and not signal error to the caller. So the caller will continue, possibly dereferencing the empty unique_ptr, leading to undefined behavior?

    MarcoFalke commented at 12:21 pm on September 10, 2021:
    The pointer is initialized in the beginning of the function. Otherwise DumpPeerAddresses(args, *addrman); wouldn’t work either.

    jonatack commented at 1:01 pm on September 10, 2021:
    Removal LGTM. Built with the suggested diff and tested.

    vasild commented at 1:09 pm on September 10, 2021:

    The pointer is initialized in the beginning of the function

    ah, well, then it is ok. ACK.

  66. sidhujag referenced this in commit 78b1e983ae on Sep 11, 2021
  67. sipa commented at 3:50 pm on October 25, 2021: member
    I’m not sure it’s entirely desirable to require user intervention when downgrading. When there is actual corruption, this may make sense as it’s a sign of a deeper problem, but wiping peers.dat when downgrading to an incompatible version seems entirely expected to me.
  68. MarcoFalke referenced this in commit b00b60ed4f on Feb 25, 2022
  69. sidhujag referenced this in commit 7da3620dbe on Feb 25, 2022
  70. Fabcien referenced this in commit dc148fa4ac on Oct 19, 2022
  71. DrahtBot locked this on Oct 30, 2022

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

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