Skip to content

Commit

Permalink
Move CAddrDB frrom db to net
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
laanwj committed Dec 4, 2013
1 parent 48ba56c commit d004d72
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 128 deletions.
110 changes: 0 additions & 110 deletions src/db.cpp
Expand Up @@ -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<unsigned char> 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;
}

18 changes: 0 additions & 18 deletions src/db.h
Expand Up @@ -305,22 +305,4 @@ class CDB
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
100 changes: 100 additions & 0 deletions src/net.cpp
Expand Up @@ -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<unsigned char> 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;
}
11 changes: 11 additions & 0 deletions src/net.h
Expand Up @@ -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

0 comments on commit d004d72

Please sign in to comment.