LCOV - code coverage report
Current view: top level - src - addrdb.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 66 83 79.5 %
Date: 2020-09-26 01:30:44 Functions: 18 18 100.0 %

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

Generated by: LCOV version 1.15