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.
9 #include "chainparams.h"
10 #include "clientversion.h"
14 #include "tinyformat.h"
17 #include <boost/filesystem.hpp>
21 pathBanlist
= GetDataDir() / "banlist.dat";
24 bool CBanDB::Write(const banmap_t
& banSet
)
26 // Generate random temporary filename
27 unsigned short randv
= 0;
28 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
29 std::string tmpfn
= strprintf("banlist.dat.%04x", randv
);
31 // serialize banlist, checksum data up to that point, then append csum
32 CDataStream
ssBanlist(SER_DISK
, CLIENT_VERSION
);
33 ssBanlist
<< FLATDATA(Params().MessageStart());
35 uint256 hash
= Hash(ssBanlist
.begin(), ssBanlist
.end());
38 // open temp output file, and associate with CAutoFile
39 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
40 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
41 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
43 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
45 // Write and commit header, data
49 catch (const std::exception
& e
) {
50 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
52 FileCommit(fileout
.Get());
55 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
56 if (!RenameOver(pathTmp
, pathBanlist
))
57 return error("%s: Rename-into-place failed", __func__
);
62 bool CBanDB::Read(banmap_t
& banSet
)
64 // open input file, and associate with CAutoFile
65 FILE *file
= fopen(pathBanlist
.string().c_str(), "rb");
66 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
68 return error("%s: Failed to open file %s", __func__
, pathBanlist
.string());
70 // use file size to size memory buffer
71 uint64_t fileSize
= boost::filesystem::file_size(pathBanlist
);
72 uint64_t dataSize
= 0;
73 // Don't try to resize to a negative number if file is small
74 if (fileSize
>= sizeof(uint256
))
75 dataSize
= fileSize
- sizeof(uint256
);
76 std::vector
<unsigned char> vchData
;
77 vchData
.resize(dataSize
);
80 // read data and checksum from file
82 filein
.read((char *)&vchData
[0], dataSize
);
85 catch (const std::exception
& e
) {
86 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
90 CDataStream
ssBanlist(vchData
, SER_DISK
, CLIENT_VERSION
);
92 // verify stored checksum matches input data
93 uint256 hashTmp
= Hash(ssBanlist
.begin(), ssBanlist
.end());
94 if (hashIn
!= hashTmp
)
95 return error("%s: Checksum mismatch, data corrupted", __func__
);
97 unsigned char pchMsgTmp
[4];
99 // de-serialize file header (network specific magic number) and ..
100 ssBanlist
>> FLATDATA(pchMsgTmp
);
102 // ... verify the network matches ours
103 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
104 return error("%s: Invalid network magic number", __func__
);
106 // de-serialize ban data
109 catch (const std::exception
& e
) {
110 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
118 pathAddr
= GetDataDir() / "peers.dat";
121 bool CAddrDB::Write(const CAddrMan
& addr
)
123 // Generate random temporary filename
124 unsigned short randv
= 0;
125 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
126 std::string tmpfn
= strprintf("peers.dat.%04x", randv
);
128 // serialize addresses, checksum data up to that point, then append csum
129 CDataStream
ssPeers(SER_DISK
, CLIENT_VERSION
);
130 ssPeers
<< FLATDATA(Params().MessageStart());
132 uint256 hash
= Hash(ssPeers
.begin(), ssPeers
.end());
135 // open temp output file, and associate with CAutoFile
136 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
137 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
138 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
139 if (fileout
.IsNull())
140 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
142 // Write and commit header, data
146 catch (const std::exception
& e
) {
147 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
149 FileCommit(fileout
.Get());
152 // replace existing peers.dat, if any, with new peers.dat.XXXX
153 if (!RenameOver(pathTmp
, pathAddr
))
154 return error("%s: Rename-into-place failed", __func__
);
159 bool CAddrDB::Read(CAddrMan
& addr
)
161 // open input file, and associate with CAutoFile
162 FILE *file
= fopen(pathAddr
.string().c_str(), "rb");
163 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
165 return error("%s: Failed to open file %s", __func__
, pathAddr
.string());
167 // use file size to size memory buffer
168 uint64_t fileSize
= boost::filesystem::file_size(pathAddr
);
169 uint64_t dataSize
= 0;
170 // Don't try to resize to a negative number if file is small
171 if (fileSize
>= sizeof(uint256
))
172 dataSize
= fileSize
- sizeof(uint256
);
173 std::vector
<unsigned char> vchData
;
174 vchData
.resize(dataSize
);
177 // read data and checksum from file
179 filein
.read((char *)&vchData
[0], dataSize
);
182 catch (const std::exception
& e
) {
183 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
187 CDataStream
ssPeers(vchData
, SER_DISK
, CLIENT_VERSION
);
189 // verify stored checksum matches input data
190 uint256 hashTmp
= Hash(ssPeers
.begin(), ssPeers
.end());
191 if (hashIn
!= hashTmp
)
192 return error("%s: Checksum mismatch, data corrupted", __func__
);
194 return Read(addr
, ssPeers
);
197 bool CAddrDB::Read(CAddrMan
& addr
, CDataStream
& ssPeers
)
199 unsigned char pchMsgTmp
[4];
201 // de-serialize file header (network specific magic number) and ..
202 ssPeers
>> FLATDATA(pchMsgTmp
);
204 // ... verify the network matches ours
205 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
206 return error("%s: Invalid network magic number", __func__
);
208 // de-serialize address data into one CAddrMan object
211 catch (const std::exception
& e
) {
212 // de-serialization has failed, ensure addrman is left in a clean state
214 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());