Fabcoin Core  0.16.2
P2P Digital Currency
addrdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 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 <fs.h>
12 #include <hash.h>
13 #include <random.h>
14 #include <streams.h>
15 #include <tinyformat.h>
16 #include <util.h>
17 
18 namespace {
19 
20 template <typename Stream, typename Data>
21 bool SerializeDB(Stream& stream, const Data& data)
22 {
23  // Write and commit header, data
24  try {
25  CHashWriter hasher(SER_DISK, CLIENT_VERSION);
26  stream << FLATDATA(Params().MessageStart()) << data;
27  hasher << FLATDATA(Params().MessageStart()) << data;
28  stream << hasher.GetHash();
29  } catch (const std::exception& e) {
30  return error("%s: Serialize or I/O error - %s", __func__, e.what());
31  }
32 
33  return true;
34 }
35 
36 template <typename Data>
37 bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data)
38 {
39  // Generate random temporary filename
40  unsigned short randv = 0;
41  GetRandBytes((unsigned char*)&randv, sizeof(randv));
42  std::string tmpfn = strprintf("%s.%04x", prefix, randv);
43 
44  // open temp output file, and associate with CAutoFile
45  fs::path pathTmp = GetDataDir() / tmpfn;
46  FILE *file = fsbridge::fopen(pathTmp, "wb");
47  CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
48  if (fileout.IsNull())
49  return error("%s: Failed to open file %s", __func__, pathTmp.string());
50 
51  // Serialize
52  if (!SerializeDB(fileout, data)) return false;
53  FileCommit(fileout.Get());
54  fileout.fclose();
55 
56  // replace existing file, if any, with new file
57  if (!RenameOver(pathTmp, path))
58  return error("%s: Rename-into-place failed", __func__);
59 
60  return true;
61 }
62 
63 template <typename Stream, typename Data>
64 bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
65 {
66  try {
67  CHashVerifier<Stream> verifier(&stream);
68  // de-serialize file header (network specific magic number) and ..
69  unsigned char pchMsgTmp[4];
70  verifier >> FLATDATA(pchMsgTmp);
71  // ... verify the network matches ours
72  if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
73  return error("%s: Invalid network magic number", __func__);
74 
75  // de-serialize data
76  verifier >> data;
77 
78  // verify checksum
79  if (fCheckSum) {
80  uint256 hashTmp;
81  stream >> hashTmp;
82  if (hashTmp != verifier.GetHash()) {
83  return error("%s: Checksum mismatch, data corrupted", __func__);
84  }
85  }
86  }
87  catch (const std::exception& e) {
88  return error("%s: Deserialize or I/O error - %s", __func__, e.what());
89  }
90 
91  return true;
92 }
93 
94 template <typename Data>
95 bool DeserializeFileDB(const fs::path& path, Data& data)
96 {
97  // open input file, and associate with CAutoFile
98  FILE *file = fsbridge::fopen(path, "rb");
99  CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
100  if (filein.IsNull())
101  return error("%s: Failed to open file %s", __func__, path.string());
102 
103  return DeserializeDB(filein, data);
104 }
105 
106 }
107 
109 {
110  pathBanlist = GetDataDir() / "banlist.dat";
111 }
112 
113 bool CBanDB::Write(const banmap_t& banSet)
114 {
115  return SerializeFileDB("banlist", pathBanlist, banSet);
116 }
117 
118 bool CBanDB::Read(banmap_t& banSet)
119 {
120  return DeserializeFileDB(pathBanlist, banSet);
121 }
122 
124 {
125  pathAddr = GetDataDir() / "peers.dat";
126 }
127 
128 bool CAddrDB::Write(const CAddrMan& addr)
129 {
130  return SerializeFileDB("peers", pathAddr, addr);
131 }
132 
134 {
135  return DeserializeFileDB(pathAddr, addr);
136 }
137 
138 bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
139 {
140  bool ret = DeserializeDB(ssPeers, addr, false);
141  if (!ret) {
142  // Ensure addrman is left in a clean state
143  addr.Clear();
144  }
145  return ret;
146 }
bool error(const char *fmt, const Args &...args)
Definition: util.h:178
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:5
void FileCommit(FILE *file)
Definition: util.cpp:744
CBanDB()
Definition: addrdb.cpp:108
#define strprintf
Definition: tinyformat.h:1054
CAddrDB()
Definition: addrdb.cpp:123
const char * prefix
Definition: rest.cpp:623
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:146
#define FLATDATA(obj)
Definition: serialize.h:388
Reads data from an underlying stream, while hashing the read data.
Definition: hash.h:165
Stochastical (IP) address manager.
Definition: addrman.h:182
std::map< CSubNet, CBanEntry > banmap_t
Definition: addrdb.h:77
bool Write(const CAddrMan &addr)
Definition: addrdb.cpp:128
bool RenameOver(fs::path src, fs::path dest)
Definition: util.cpp:714
bool Write(const banmap_t &banSet)
Definition: addrdb.cpp:113
fs::path pathBanlist
Definition: addrdb.h:95
bool Read(banmap_t &banSet)
Definition: addrdb.cpp:118
256-bit opaque blob.
Definition: uint256.h:132
void Clear()
Definition: addrman.h:456
const CChainParams & Params()
Return the currently selected parameters.
void GetRandBytes(unsigned char *buf, int num)
Functions to gather random data via the OpenSSL PRNG.
Definition: random.cpp:273
#define e(i)
Definition: sha.cpp:733
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:130
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:623
uint8_t const * data
Definition: sha3.h:19
bool Read(CAddrMan &addr)
Definition: addrdb.cpp:133
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:455