示例#1
0
bool CBitcoinAddrDb::Read(CAddrMan& addr)
{
	boost::filesystem::path pathAddr = GetDataDir() / m_addrFileName;
	// open input file, and associate with CAutoFile
	FILE *file = fopen(pathAddr.string().c_str(), "rb");
	CAutoFile filein = CAutoFile(file, SER_DISK, BITCOIN_CLIENT_VERSION);
	if (!filein)
	{
		return false;
	}

	// 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 false;
	}
	filein.fclose();

	CDataStream ssPeers(vchData, SER_DISK, BITCOIN_CLIENT_VERSION);

	// verify stored checksum matches input data
	uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end());
	if (hashIn != hashTmp)
	{
		return false;
	}
	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, BitcoinMessageStart, sizeof(pchMsgTmp)))
		{
			return false;
		}
		// de-serialize address data into one CAddrMan object
		ssPeers >> addr;
	}
	catch (std::exception &e)
	{
		return false;
	}
	return true;
}
示例#2
0
bool CAddrDB::Read(CAddrMan& addr)
{
    // open input file, and associate with CAutoFile
    FILE *file = fopen(pathAddr.string().c_str(), "rb");
    CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
    if (filein.IsNull())
        return error("%s: Failed to open file %s", __func__, pathAddr.string());

    // use file size to size memory buffer
    uint64_t fileSize = boost::filesystem::file_size(pathAddr);
    uint64_t dataSize = 0;
    // Don't try to resize to a negative number if file is small
    if (fileSize >= sizeof(uint256))
        dataSize = fileSize - sizeof(uint256);
    std::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 (const std::exception& e) {
        return error("%s: Deserialize or I/O error - %s", __func__, e.what());
    }
    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("%s: Checksum mismatch, data corrupted", __func__);

    return Read(addr, ssPeers);
}
示例#3
0
bool CAddrDB::Write(const CAddrMan& addr)
{
    // Generate random temporary filename
    unsigned short randv = 0;
    GetRandBytes((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(file, SER_DISK, CLIENT_VERSION);
    if (fileout.IsNull())
        return error("%s: Failed to open file %s", __func__, pathTmp.string());

    // Write and commit header, data
    try {
        fileout << ssPeers;
    }
    catch (const std::exception& e) {
        return error("%s: Serialize or I/O error - %s", __func__, e.what());
    }
    FileCommit(fileout.Get());
    fileout.fclose();

    // replace existing peers.dat, if any, with new peers.dat.XXXX
    if (!RenameOver(pathTmp, pathAddr))
        return error("%s: Rename-into-place failed", __func__);

    return true;
}