aboutsummaryrefslogtreecommitdiff
path: root/src/addrdb.cpp
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-08-21 16:17:52 +0200
committerMarcoFalke <falke.marco@gmail.com>2021-09-09 09:20:43 +0200
commitfa55c3dc1b4bbdc6a53bd11fa6c0b2ec6bbb64ae (patch)
tree7c8b699fa4c19748eb427adb92dcd91ae4379f7c /src/addrdb.cpp
parentfa4e2ccfd8ae96c381947285bef47cb39474ac89 (diff)
downloadbitcoin-fa55c3dc1b4bbdc6a53bd11fa6c0b2ec6bbb64ae.tar.xz
Raise InitError when peers.dat is invalid or corrupted
Diffstat (limited to 'src/addrdb.cpp')
-rw-r--r--src/addrdb.cpp77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index 77f0897a7f..1e73750ce3 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -21,6 +21,12 @@
#include <util/translation.h>
namespace {
+
+class DbNotFoundError : public std::exception
+{
+ using std::exception::exception;
+};
+
template <typename Stream, typename Data>
bool SerializeDB(Stream& stream, const Data& data)
{
@@ -78,47 +84,40 @@ bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data
}
template <typename Stream, typename Data>
-bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
+void DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
{
- try {
- CHashVerifier<Stream> verifier(&stream);
- // de-serialize file header (network specific magic number) and ..
- unsigned char pchMsgTmp[4];
- verifier >> pchMsgTmp;
- // ... verify the network matches ours
- if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
- return error("%s: Invalid network magic number", __func__);
-
- // de-serialize data
- verifier >> data;
-
- // verify checksum
- if (fCheckSum) {
- uint256 hashTmp;
- stream >> hashTmp;
- if (hashTmp != verifier.GetHash()) {
- return error("%s: Checksum mismatch, data corrupted", __func__);
- }
+ CHashVerifier<Stream> verifier(&stream);
+ // de-serialize file header (network specific magic number) and ..
+ unsigned char pchMsgTmp[4];
+ verifier >> pchMsgTmp;
+ // ... verify the network matches ours
+ if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) {
+ throw std::runtime_error{"Invalid network magic number"};
+ }
+
+ // de-serialize data
+ verifier >> data;
+
+ // verify checksum
+ if (fCheckSum) {
+ uint256 hashTmp;
+ stream >> hashTmp;
+ if (hashTmp != verifier.GetHash()) {
+ throw std::runtime_error{"Checksum mismatch, data corrupted"};
}
}
- catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
- }
-
- return true;
}
template <typename Data>
-bool DeserializeFileDB(const fs::path& path, Data& data, int version)
+void DeserializeFileDB(const fs::path& path, Data& data, int version)
{
// open input file, and associate with CAutoFile
FILE* file = fsbridge::fopen(path, "rb");
CAutoFile filein(file, SER_DISK, version);
if (filein.IsNull()) {
- LogPrintf("Missing or invalid file %s\n", path.string());
- return false;
+ throw DbNotFoundError{};
}
- return DeserializeDB(filein, data);
+ DeserializeDB(filein, data);
}
} // namespace
@@ -177,9 +176,9 @@ bool DumpPeerAddresses(const ArgsManager& args, const CAddrMan& addr)
return SerializeFileDB("peers", pathAddr, addr, CLIENT_VERSION);
}
-bool ReadFromStream(CAddrMan& addr, CDataStream& ssPeers)
+void ReadFromStream(CAddrMan& addr, CDataStream& ssPeers)
{
- return DeserializeDB(ssPeers, addr, false);
+ DeserializeDB(ssPeers, addr, false);
}
std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const ArgsManager& args, std::unique_ptr<CAddrMan>& addrman)
@@ -189,13 +188,18 @@ std::optional<bilingual_str> LoadAddrman(const std::vector<bool>& asmap, const A
int64_t nStart = GetTimeMillis();
const auto path_addr{args.GetDataDirNet() / "peers.dat"};
- if (DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION)) {
+ try {
+ DeserializeFileDB(path_addr, *addrman, CLIENT_VERSION);
LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman->size(), GetTimeMillis() - nStart);
- } else {
+ } catch (const DbNotFoundError&) {
// Addrman can be in an inconsistent state after failure, reset it
addrman = std::make_unique<CAddrMan>(asmap, /* deterministic */ false, /* consistency_check_ratio */ check_addrman);
- LogPrintf("Recreating peers.dat\n");
+ LogPrintf("Creating peers.dat because the file was not found (%s)\n", path_addr);
DumpPeerAddresses(args, *addrman);
+ } catch (const std::exception& e) {
+ addrman = nullptr;
+ 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) to have a new one created on the next start."),
+ e.what(), PACKAGE_BUGREPORT, path_addr);
}
return std::nullopt;
}
@@ -209,9 +213,10 @@ void DumpAnchors(const fs::path& anchors_db_path, const std::vector<CAddress>& a
std::vector<CAddress> ReadAnchors(const fs::path& anchors_db_path)
{
std::vector<CAddress> anchors;
- if (DeserializeFileDB(anchors_db_path, anchors, CLIENT_VERSION | ADDRV2_FORMAT)) {
+ try {
+ DeserializeFileDB(anchors_db_path, anchors, CLIENT_VERSION | ADDRV2_FORMAT);
LogPrintf("Loaded %i addresses from %s\n", anchors.size(), anchors_db_path.filename());
- } else {
+ } catch (const std::exception&) {
anchors.clear();
}