LCOV - code coverage report
Current view: top level - src - addrdb.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 56 69 81.2 %
Date: 2025-02-23 09:33:43 Functions: 16 16 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2015 The Bitcoin Core developers
       3             : // Copyright (c) 2020-2021 The PIVX Core developers
       4             : // Distributed under the MIT software license, see the accompanying
       5             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       6             : 
       7             : #include "addrdb.h"
       8             : 
       9             : #include "addrman.h"
      10             : #include "chainparams.h"
      11             : #include "clientversion.h"
      12             : #include "hash.h"
      13             : #include "random.h"
      14             : #include "streams.h"
      15             : #include "tinyformat.h"
      16             : #include "util/system.h"
      17             : 
      18             : #include <cstdint>
      19             : 
      20             : namespace {
      21             : 
      22             : template <typename Stream, typename Data>
      23         923 : bool SerializeDB(Stream& stream, const Data& data)
      24             : {
      25             :     // Write and commit header, data
      26             :     try {
      27         923 :         CHashWriter hasher(SER_DISK, CLIENT_VERSION);
      28         923 :         stream << Params().MessageStart() << data;
      29         923 :         hasher << Params().MessageStart() << data;
      30         923 :         stream << hasher.GetHash();
      31           0 :     } catch (const std::exception& e) {
      32           0 :         return error("%s: Serialize or I/O error - %s", __func__, e.what());
      33             :     }
      34             : 
      35         923 :     return true;
      36             : }
      37             : 
      38             : template <typename Data>
      39         923 : bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data)
      40             : {
      41             :     // Generate random temporary filename
      42         923 :     uint16_t randv = 0;
      43         923 :     GetRandBytes((unsigned char*)&randv, sizeof(randv));
      44        1846 :     std::string tmpfn = strprintf("%s.%04x", prefix, randv);
      45             : 
      46             :     // open temp output file, and associate with CAutoFile
      47        1846 :     fs::path pathTmp = GetDataDir() / tmpfn;
      48         923 :     FILE *file = fsbridge::fopen(pathTmp, "wb");
      49        1846 :     CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
      50         923 :     if (fileout.IsNull()) {
      51           0 :         fileout.fclose();
      52           0 :         remove(pathTmp);
      53           0 :         return error("%s: Failed to open file %s", __func__, pathTmp.string());
      54             :     }
      55             : 
      56             :     // Serialize
      57         923 :     if (!SerializeDB(fileout, data)) {
      58           0 :         fileout.fclose();
      59         923 :         remove(pathTmp);
      60             :         return false;
      61             :     }
      62         923 :     if (!FileCommit(fileout.Get())) {
      63           0 :         fileout.fclose();
      64           0 :         remove(pathTmp);
      65           0 :         return error("%s: Failed to flush file %s", __func__, pathTmp.string());
      66             :     }
      67         923 :     fileout.fclose();
      68             : 
      69             :     // replace existing file, if any, with new file
      70        3692 :     if (!RenameOver(pathTmp, path)) {
      71           0 :         remove(pathTmp);
      72           0 :         return error("%s: Rename-into-place failed", __func__);
      73             :     }
      74             : 
      75             :     return true;
      76             : }
      77             : 
      78             : template <typename Stream, typename Data>
      79         173 : bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
      80             : {
      81             :     try {
      82         173 :         CHashVerifier<Stream> verifier(&stream);
      83             :         // de-serialize file header (network specific magic number) and ..
      84             :         unsigned char pchMsgTmp[4];
      85         173 :         verifier >> pchMsgTmp;
      86             :         // ... verify the network matches ours
      87         173 :         if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)) != 0)
      88           0 :             return error("%s: Invalid network magic number", __func__);
      89             : 
      90             :         // de-serialize data
      91         172 :         verifier >> data;
      92             : 
      93             :         // verify checksum
      94         172 :         if (fCheckSum) {
      95         171 :             uint256 hashTmp;
      96         171 :             stream >> hashTmp;
      97         171 :             if (hashTmp != verifier.GetHash()) {
      98           0 :                 return error("%s: Checksum mismatch, data corrupted", __func__);
      99             :             }
     100             :         }
     101             :     }
     102           1 :     catch (const std::exception& e) {
     103           1 :         return error("%s: Deserialize or I/O error - %s", __func__, e.what());
     104             :     }
     105             : 
     106         172 :     return true;
     107             : }
     108             : 
     109             : template <typename Data>
     110         710 : bool DeserializeFileDB(const fs::path& path, Data& data)
     111             : {
     112             :     // open input file, and associate with CAutoFile
     113         710 :     FILE *file = fsbridge::fopen(path, "rb");
     114        1420 :     CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
     115         710 :     if (filein.IsNull())
     116         539 :         return error("%s: Failed to open file %s", __func__, path.string());
     117             : 
     118         171 :     return DeserializeDB(filein, data);
     119             : }
     120             : 
     121             : }
     122             : 
     123         652 : CBanDB::CBanDB()
     124             : {
     125         652 :     pathBanlist = GetDataDir() / "banlist.dat";
     126         652 : }
     127             : 
     128         297 : bool CBanDB::Write(const banmap_t& banSet)
     129             : {
     130         297 :     return SerializeFileDB("banlist", pathBanlist, banSet);
     131             : }
     132             : 
     133         355 : bool CBanDB::Read(banmap_t& banSet)
     134             : {
     135         355 :     return DeserializeFileDB(pathBanlist, banSet);
     136             : }
     137             : 
     138         981 : CAddrDB::CAddrDB()
     139             : {
     140         981 :     pathAddr = GetDataDir() / "peers.dat";
     141         981 : }
     142             : 
     143         626 : bool CAddrDB::Write(const CAddrMan& addr)
     144             : {
     145         626 :     return SerializeFileDB("peers", pathAddr, addr);
     146             : }
     147             : 
     148         355 : bool CAddrDB::Read(CAddrMan& addr)
     149             : {
     150         355 :     return DeserializeFileDB(pathAddr, addr);
     151             : }
     152             : 
     153           2 : bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
     154             : {
     155           2 :     bool ret = DeserializeDB(ssPeers, addr, false);
     156           2 :     if (!ret) {
     157             :         // Ensure addrman is left in a clean state
     158           1 :         addr.Clear();
     159             :     }
     160           2 :     return ret;
     161             : }

Generated by: LCOV version 1.14