From d004d7279ff21b7ee90207a850ec26ba044799bb Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 29 Nov 2013 16:33:34 +0100 Subject: [PATCH] Move CAddrDB frrom db to net This was a leftover from the times in which peers.dat depended in BDB. Other functions in db.cpp still depend on BerkelyDB, to be able to compile without BDB this (small) functionality needs to be moved to another file. --- src/db.cpp | 110 ---------------------------------------------------- src/db.h | 18 --------- src/net.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++++++ src/net.h | 11 ++++++ 4 files changed, 111 insertions(+), 128 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index a286d9f72..1f2ee1c55 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -479,113 +479,3 @@ void CDBEnv::Flush(bool fShutdown) } } - - - - - - - - - - -// -// CAddrDB -// - -CAddrDB::CAddrDB() -{ - pathAddr = GetDataDir() / "peers.dat"; -} - -bool CAddrDB::Write(const CAddrMan& addr) -{ - // Generate random temporary filename - unsigned short randv = 0; - RAND_bytes((unsigned char *)&randv, sizeof(randv)); - std::string tmpfn = strprintf("peers.dat.%04x", randv); - - // serialize addresses, checksum data up to that point, then append csum - CDataStream ssPeers(SER_DISK, CLIENT_VERSION); - ssPeers << FLATDATA(Params().MessageStart()); - ssPeers << addr; - uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); - ssPeers << hash; - - // open temp output file, and associate with CAutoFile - boost::filesystem::path pathTmp = GetDataDir() / tmpfn; - FILE *file = fopen(pathTmp.string().c_str(), "wb"); - CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); - if (!fileout) - return error("CAddrman::Write() : open failed"); - - // Write and commit header, data - try { - fileout << ssPeers; - } - catch (std::exception &e) { - return error("CAddrman::Write() : I/O error"); - } - FileCommit(fileout); - fileout.fclose(); - - // replace existing peers.dat, if any, with new peers.dat.XXXX - if (!RenameOver(pathTmp, pathAddr)) - return error("CAddrman::Write() : Rename-into-place failed"); - - return true; -} - -bool CAddrDB::Read(CAddrMan& addr) -{ - // open input file, and associate with CAutoFile - FILE *file = fopen(pathAddr.string().c_str(), "rb"); - CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); - if (!filein) - return error("CAddrman::Read() : open failed"); - - // use file size to size memory buffer - int fileSize = GetFilesize(filein); - int dataSize = fileSize - sizeof(uint256); - //Don't try to resize to a negative number if file is small - if ( dataSize < 0 ) dataSize = 0; - vector vchData; - vchData.resize(dataSize); - uint256 hashIn; - - // read data and checksum from file - try { - filein.read((char *)&vchData[0], dataSize); - filein >> hashIn; - } - catch (std::exception &e) { - return error("CAddrman::Read() 2 : I/O error or stream data corrupted"); - } - filein.fclose(); - - CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); - - // verify stored checksum matches input data - uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); - if (hashIn != hashTmp) - return error("CAddrman::Read() : checksum mismatch; data corrupted"); - - unsigned char pchMsgTmp[4]; - try { - // de-serialize file header (network specific magic number) and .. - ssPeers >> FLATDATA(pchMsgTmp); - - // ... verify the network matches ours - if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) - return error("CAddrman::Read() : invalid network magic number"); - - // de-serialize address data into one CAddrMan object - ssPeers >> addr; - } - catch (std::exception &e) { - return error("CAddrman::Read() : I/O error or stream data corrupted"); - } - - return true; -} - diff --git a/src/db.h b/src/db.h index e041a5930..66d7f3191 100644 --- a/src/db.h +++ b/src/db.h @@ -305,22 +305,4 @@ public: bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL); }; - - - - - - - -/** Access to the (IP) address database (peers.dat) */ -class CAddrDB -{ -private: - boost::filesystem::path pathAddr; -public: - CAddrDB(); - bool Write(const CAddrMan& addr); - bool Read(CAddrMan& addr); -}; - #endif // BITCOIN_DB_H diff --git a/src/net.cpp b/src/net.cpp index fcef9feea..afffbdf1d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1942,3 +1942,103 @@ void CNode::Fuzz(int nChance) // (more changes exponentially less likely): Fuzz(2); } + +// +// CAddrDB +// + +CAddrDB::CAddrDB() +{ + pathAddr = GetDataDir() / "peers.dat"; +} + +bool CAddrDB::Write(const CAddrMan& addr) +{ + // Generate random temporary filename + unsigned short randv = 0; + RAND_bytes((unsigned char *)&randv, sizeof(randv)); + std::string tmpfn = strprintf("peers.dat.%04x", randv); + + // serialize addresses, checksum data up to that point, then append csum + CDataStream ssPeers(SER_DISK, CLIENT_VERSION); + ssPeers << FLATDATA(Params().MessageStart()); + ssPeers << addr; + uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); + ssPeers << hash; + + // open temp output file, and associate with CAutoFile + boost::filesystem::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!fileout) + return error("CAddrman::Write() : open failed"); + + // Write and commit header, data + try { + fileout << ssPeers; + } + catch (std::exception &e) { + return error("CAddrman::Write() : I/O error"); + } + FileCommit(fileout); + fileout.fclose(); + + // replace existing peers.dat, if any, with new peers.dat.XXXX + if (!RenameOver(pathTmp, pathAddr)) + return error("CAddrman::Write() : Rename-into-place failed"); + + return true; +} + +bool CAddrDB::Read(CAddrMan& addr) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathAddr.string().c_str(), "rb"); + CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); + if (!filein) + return error("CAddrman::Read() : open failed"); + + // use file size to size memory buffer + int fileSize = GetFilesize(filein); + int dataSize = fileSize - sizeof(uint256); + //Don't try to resize to a negative number if file is small + if ( dataSize < 0 ) dataSize = 0; + vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (std::exception &e) { + return error("CAddrman::Read() 2 : I/O error or stream data corrupted"); + } + filein.fclose(); + + CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + if (hashIn != hashTmp) + return error("CAddrman::Read() : checksum mismatch; data corrupted"); + + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (network specific magic number) and .. + ssPeers >> FLATDATA(pchMsgTmp); + + // ... verify the network matches ours + if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) + return error("CAddrman::Read() : invalid network magic number"); + + // de-serialize address data into one CAddrMan object + ssPeers >> addr; + } + catch (std::exception &e) { + return error("CAddrman::Read() : I/O error or stream data corrupted"); + } + + return true; +} diff --git a/src/net.h b/src/net.h index effce35dc..28359ea12 100644 --- a/src/net.h +++ b/src/net.h @@ -690,4 +690,15 @@ class CTransaction; void RelayTransaction(const CTransaction& tx, const uint256& hash); void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss); +/** Access to the (IP) address database (peers.dat) */ +class CAddrDB +{ +private: + boost::filesystem::path pathAddr; +public: + CAddrDB(); + bool Write(const CAddrMan& addr); + bool Read(CAddrMan& addr); +}; + #endif