Merge #11667: Add scripts to dumpwallet RPC
[bitcoinplatinum.git] / src / addrdb.cpp
blob7d7f34863dae1b1babaf8fc8706c726ccfe7231f
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include <addrdb.h>
8 #include <addrman.h>
9 #include <chainparams.h>
10 #include <clientversion.h>
11 #include <hash.h>
12 #include <random.h>
13 #include <streams.h>
14 #include <tinyformat.h>
15 #include <util.h>
17 namespace {
19 template <typename Stream, typename Data>
20 bool SerializeDB(Stream& stream, const Data& data)
22 // Write and commit header, data
23 try {
24 CHashWriter hasher(SER_DISK, CLIENT_VERSION);
25 stream << FLATDATA(Params().MessageStart()) << data;
26 hasher << FLATDATA(Params().MessageStart()) << data;
27 stream << hasher.GetHash();
28 } catch (const std::exception& e) {
29 return error("%s: Serialize or I/O error - %s", __func__, e.what());
32 return true;
35 template <typename Data>
36 bool SerializeFileDB(const std::string& prefix, const fs::path& path, const Data& data)
38 // Generate random temporary filename
39 unsigned short randv = 0;
40 GetRandBytes((unsigned char*)&randv, sizeof(randv));
41 std::string tmpfn = strprintf("%s.%04x", prefix, randv);
43 // open temp output file, and associate with CAutoFile
44 fs::path pathTmp = GetDataDir() / tmpfn;
45 FILE *file = fsbridge::fopen(pathTmp, "wb");
46 CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
47 if (fileout.IsNull())
48 return error("%s: Failed to open file %s", __func__, pathTmp.string());
50 // Serialize
51 if (!SerializeDB(fileout, data)) return false;
52 FileCommit(fileout.Get());
53 fileout.fclose();
55 // replace existing file, if any, with new file
56 if (!RenameOver(pathTmp, path))
57 return error("%s: Rename-into-place failed", __func__);
59 return true;
62 template <typename Stream, typename Data>
63 bool DeserializeDB(Stream& stream, Data& data, bool fCheckSum = true)
65 try {
66 CHashVerifier<Stream> verifier(&stream);
67 // de-serialize file header (network specific magic number) and ..
68 unsigned char pchMsgTmp[4];
69 verifier >> FLATDATA(pchMsgTmp);
70 // ... verify the network matches ours
71 if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
72 return error("%s: Invalid network magic number", __func__);
74 // de-serialize data
75 verifier >> data;
77 // verify checksum
78 if (fCheckSum) {
79 uint256 hashTmp;
80 stream >> hashTmp;
81 if (hashTmp != verifier.GetHash()) {
82 return error("%s: Checksum mismatch, data corrupted", __func__);
86 catch (const std::exception& e) {
87 return error("%s: Deserialize or I/O error - %s", __func__, e.what());
90 return true;
93 template <typename Data>
94 bool DeserializeFileDB(const fs::path& path, Data& data)
96 // open input file, and associate with CAutoFile
97 FILE *file = fsbridge::fopen(path, "rb");
98 CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
99 if (filein.IsNull())
100 return error("%s: Failed to open file %s", __func__, path.string());
102 return DeserializeDB(filein, data);
107 CBanDB::CBanDB()
109 pathBanlist = GetDataDir() / "banlist.dat";
112 bool CBanDB::Write(const banmap_t& banSet)
114 return SerializeFileDB("banlist", pathBanlist, banSet);
117 bool CBanDB::Read(banmap_t& banSet)
119 return DeserializeFileDB(pathBanlist, banSet);
122 CAddrDB::CAddrDB()
124 pathAddr = GetDataDir() / "peers.dat";
127 bool CAddrDB::Write(const CAddrMan& addr)
129 return SerializeFileDB("peers", pathAddr, addr);
132 bool CAddrDB::Read(CAddrMan& addr)
134 return DeserializeFileDB(pathAddr, addr);
137 bool CAddrDB::Read(CAddrMan& addr, CDataStream& ssPeers)
139 bool ret = DeserializeDB(ssPeers, addr, false);
140 if (!ret) {
141 // Ensure addrman is left in a clean state
142 addr.Clear();
144 return ret;