dash/src/flat-database.h
PastaPastaPasta 8a1ec935a0
Backport 11651 (#3358)
* scripted-diff: Replace #include "" with #include <> (ryanofsky)

-BEGIN VERIFY SCRIPT-
for f in \
  src/*.cpp \
  src/*.h \
  src/bench/*.cpp \
  src/bench/*.h \
  src/compat/*.cpp \
  src/compat/*.h \
  src/consensus/*.cpp \
  src/consensus/*.h \
  src/crypto/*.cpp \
  src/crypto/*.h \
  src/crypto/ctaes/*.h \
  src/policy/*.cpp \
  src/policy/*.h \
  src/primitives/*.cpp \
  src/primitives/*.h \
  src/qt/*.cpp \
  src/qt/*.h \
  src/qt/test/*.cpp \
  src/qt/test/*.h \
  src/rpc/*.cpp \
  src/rpc/*.h \
  src/script/*.cpp \
  src/script/*.h \
  src/support/*.cpp \
  src/support/*.h \
  src/support/allocators/*.h \
  src/test/*.cpp \
  src/test/*.h \
  src/wallet/*.cpp \
  src/wallet/*.h \
  src/wallet/test/*.cpp \
  src/wallet/test/*.h \
  src/zmq/*.cpp \
  src/zmq/*.h
do
  base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f
done
-END VERIFY SCRIPT-

Signed-off-by: Pasta <pasta@dashboost.org>

* scripted-diff: Replace #include "" with #include <> (Dash Specific)

-BEGIN VERIFY SCRIPT-
for f in \
  src/bls/*.cpp \
  src/bls/*.h \
  src/evo/*.cpp \
  src/evo/*.h \
  src/governance/*.cpp \
  src/governance/*.h \
  src/llmq/*.cpp \
  src/llmq/*.h \
  src/masternode/*.cpp \
  src/masternode/*.h \
  src/privatesend/*.cpp \
  src/privatesend/*.h
do
  base=${f%/*}/ relbase=${base#src/} sed -i "s:#include \"\(.*\)\"\(.*\):if test -e \$base'\\1'; then echo \"#include <\"\$relbase\"\\1>\\2\"; else echo \"#include <\\1>\\2\"; fi:e" $f
done
-END VERIFY SCRIPT-

Signed-off-by: Pasta <pasta@dashboost.org>

* build: Remove -I for everything but project root

Remove -I from build system for everything but the project root,
and built-in dependencies.

Signed-off-by: Pasta <pasta@dashboost.org>

# Conflicts:
#	src/Makefile.test.include

* qt: refactor: Use absolute include paths in .ui files

* qt: refactor: Changes to make include paths absolute

This makes all include paths in the GUI absolute.

Many changes are involved as every single source file in
src/qt/ assumes to be able to use relative includes.

Signed-off-by: Pasta <pasta@dashboost.org>

# Conflicts:
#	src/qt/dash.cpp
#	src/qt/optionsmodel.cpp
#	src/qt/test/rpcnestedtests.cpp

* test: refactor: Use absolute include paths for test data files

* Recommend #include<> syntax in developer notes

* refactor: Include obj/build.h instead of build.h

* END BACKPORT #11651 Remove trailing whitespace causing travis failure

* fix backport 11651

Signed-off-by: Pasta <pasta@dashboost.org>

* More of 11651

* fix blockchain.cpp

Signed-off-by: pasta <pasta@dashboost.org>

* Add missing "qt/" in includes

* Add missing "test/" in includes

* Fix trailing whitespaces

Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com>
Co-authored-by: Russell Yanofsky <russ@yanofsky.org>
Co-authored-by: MeshCollider <dobsonsa68@gmail.com>
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
2020-03-20 01:46:56 +03:00

229 lines
6.9 KiB
C++

// Copyright (c) 2014-2020 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef FLAT_DATABASE_H
#define FLAT_DATABASE_H
#include <chainparams.h>
#include <clientversion.h>
#include <fs.h>
#include <hash.h>
#include <streams.h>
#include <util.h>
/**
* Generic Dumping and Loading
* ---------------------------
*/
template<typename T>
class CFlatDB
{
private:
enum ReadResult {
Ok,
FileError,
HashReadError,
IncorrectHash,
IncorrectMagicMessage,
IncorrectMagicNumber,
IncorrectFormat
};
fs::path pathDB;
std::string strFilename;
std::string strMagicMessage;
bool Write(const T& objToSave)
{
// LOCK(objToSave.cs);
int64_t nStart = GetTimeMillis();
// serialize, checksum data up to that point, then append checksum
CDataStream ssObj(SER_DISK, CLIENT_VERSION);
ssObj << strMagicMessage; // specific magic message for this type of object
ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
ssObj << objToSave;
uint256 hash = Hash(ssObj.begin(), ssObj.end());
ssObj << hash;
// open output file, and associate with CAutoFile
FILE *file = fopen(pathDB.string().c_str(), "wb");
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s: Failed to open file %s", __func__, pathDB.string());
// Write and commit header, data
try {
fileout << ssObj;
}
catch (std::exception &e) {
return error("%s: Serialize or I/O error - %s", __func__, e.what());
}
fileout.fclose();
LogPrintf("Written info to %s %dms\n", strFilename, GetTimeMillis() - nStart);
LogPrintf(" %s\n", objToSave.ToString());
return true;
}
ReadResult Read(T& objToLoad, bool fDryRun = false)
{
//LOCK(objToLoad.cs);
int64_t nStart = GetTimeMillis();
// open input file, and associate with CAutoFile
FILE *file = fopen(pathDB.string().c_str(), "rb");
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
{
error("%s: Failed to open file %s", __func__, pathDB.string());
return FileError;
}
// use file size to size memory buffer
int fileSize = fs::file_size(pathDB);
int dataSize = fileSize - sizeof(uint256);
// Don't try to resize to a negative number if file is small
if (dataSize < 0)
dataSize = 0;
std::vector<unsigned char> vchData;
vchData.resize(dataSize);
uint256 hashIn;
// read data and checksum from file
try {
filein.read((char *)vchData.data(), dataSize);
filein >> hashIn;
}
catch (std::exception &e) {
error("%s: Deserialize or I/O error - %s", __func__, e.what());
return HashReadError;
}
filein.fclose();
CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);
// verify stored checksum matches input data
uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
if (hashIn != hashTmp)
{
error("%s: Checksum mismatch, data corrupted", __func__);
return IncorrectHash;
}
unsigned char pchMsgTmp[4];
std::string strMagicMessageTmp;
try {
// de-serialize file header (file specific magic message) and ..
ssObj >> strMagicMessageTmp;
// ... verify the message matches predefined one
if (strMagicMessage != strMagicMessageTmp)
{
error("%s: Invalid magic message", __func__);
return IncorrectMagicMessage;
}
// de-serialize file header (network specific magic number) and ..
ssObj >> FLATDATA(pchMsgTmp);
// ... verify the network matches ours
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
{
error("%s: Invalid network magic number", __func__);
return IncorrectMagicNumber;
}
// de-serialize data into T object
ssObj >> objToLoad;
}
catch (std::exception &e) {
objToLoad.Clear();
error("%s: Deserialize or I/O error - %s", __func__, e.what());
return IncorrectFormat;
}
LogPrintf("Loaded info from %s %dms\n", strFilename, GetTimeMillis() - nStart);
LogPrintf(" %s\n", objToLoad.ToString());
if(!fDryRun) {
LogPrintf("%s: Cleaning....\n", __func__);
objToLoad.CheckAndRemove();
LogPrintf(" %s\n", objToLoad.ToString());
}
return Ok;
}
public:
CFlatDB(std::string strFilenameIn, std::string strMagicMessageIn)
{
pathDB = GetDataDir() / strFilenameIn;
strFilename = strFilenameIn;
strMagicMessage = strMagicMessageIn;
}
bool Load(T& objToLoad)
{
LogPrintf("Reading info from %s...\n", strFilename);
ReadResult readResult = Read(objToLoad);
if (readResult == FileError)
LogPrintf("Missing file %s, will try to recreate\n", strFilename);
else if (readResult != Ok)
{
LogPrintf("Error reading %s: ", strFilename);
if(readResult == IncorrectFormat)
{
LogPrintf("%s: Magic is ok but data has invalid format, will try to recreate\n", __func__);
}
else {
LogPrintf("%s: File format is unknown or invalid, please fix it manually\n", __func__);
// program should exit with an error
return false;
}
}
return true;
}
bool Dump(T& objToSave)
{
int64_t nStart = GetTimeMillis();
LogPrintf("Verifying %s format...\n", strFilename);
T tmpObjToLoad;
ReadResult readResult = Read(tmpObjToLoad, true);
// there was an error and it was not an error on file opening => do not proceed
if (readResult == FileError)
LogPrintf("Missing file %s, will try to recreate\n", strFilename);
else if (readResult != Ok)
{
LogPrintf("Error reading %s: ", strFilename);
if(readResult == IncorrectFormat)
LogPrintf("%s: Magic is ok but data has invalid format, will try to recreate\n", __func__);
else
{
LogPrintf("%s: File format is unknown or invalid, please fix it manually\n", __func__);
return false;
}
}
LogPrintf("Writing info to %s...\n", strFilename);
Write(objToSave);
LogPrintf("%s dump finished %dms\n", strFilename, GetTimeMillis() - nStart);
return true;
}
};
#endif