scripted-diff: Rename wallet database classes
-BEGIN VERIFY SCRIPT- sed -i 's/\<CWalletDBWrapper\>/BerkeleyDatabase/g' src/wallet/db.h src/wallet/db.cpp sed -i '/statuses/i/** Backend-agnostic database type. */\nusing WalletDatabase = BerkeleyDatabase\;\n' src/wallet/walletdb.h ren() { git grep -l "\<$1\>" 'src/*.cpp' 'src/*.h' ':(exclude)*dbwrapper*' test | xargs sed -i "s:\<$1\>:$2:g"; } ren CDBEnv BerkeleyEnvironment ren CDB BerkeleyBatch ren CWalletDBWrapper WalletDatabase ren CWalletDB WalletBatch ren dbw database ren m_dbw m_database ren walletdb batch ren pwalletdb batch ren pwalletdbIn batch_in ren wallet/batch.h wallet/walletdb.h ren pwalletdbEncryption encrypted_batch -END VERIFY SCRIPT-
This commit is contained in:
parent
b2e5fe8b55
commit
ea23945dbc
14 changed files with 318 additions and 315 deletions
|
@ -33,7 +33,7 @@ static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<CO
|
||||||
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
|
// (https://github.com/bitcoin/bitcoin/issues/7883#issuecomment-224807484)
|
||||||
static void CoinSelection(benchmark::State& state)
|
static void CoinSelection(benchmark::State& state)
|
||||||
{
|
{
|
||||||
const CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
const CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
std::vector<COutput> vCoins;
|
std::vector<COutput> vCoins;
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ void TestGUI()
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
|
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
|
||||||
}
|
}
|
||||||
CWallet wallet("mock", CWalletDBWrapper::CreateMock());
|
CWallet wallet("mock", WalletDatabase::CreateMock());
|
||||||
bool firstRun;
|
bool firstRun;
|
||||||
wallet.LoadWallet(firstRun);
|
wallet.LoadWallet(firstRun);
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,7 @@ BOOST_AUTO_TEST_CASE(util_ParseHex)
|
||||||
result = ParseHex("12 34 56 78");
|
result = ParseHex("12 34 56 78");
|
||||||
BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
|
BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
|
||||||
|
|
||||||
// Leading space must be supported (used in CDBEnv::Salvage)
|
// Leading space must be supported (used in BerkeleyEnvironment::Salvage)
|
||||||
result = ParseHex(" 89 34 56 78");
|
result = ParseHex(" 89 34 56 78");
|
||||||
BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
|
BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,14 @@ namespace {
|
||||||
//! (https://docs.oracle.com/cd/E17275_01/html/programmer_reference/program_copy.html),
|
//! (https://docs.oracle.com/cd/E17275_01/html/programmer_reference/program_copy.html),
|
||||||
//! so bitcoin should never create different databases with the same fileid, but
|
//! so bitcoin should never create different databases with the same fileid, but
|
||||||
//! this error can be triggered if users manually copy database files.
|
//! this error can be triggered if users manually copy database files.
|
||||||
void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db)
|
void CheckUniqueFileid(const BerkeleyEnvironment& env, const std::string& filename, Db& db)
|
||||||
{
|
{
|
||||||
if (env.IsMock()) return;
|
if (env.IsMock()) return;
|
||||||
|
|
||||||
u_int8_t fileid[DB_FILE_ID_LEN];
|
u_int8_t fileid[DB_FILE_ID_LEN];
|
||||||
int ret = db.get_mpf()->get_fileid(fileid);
|
int ret = db.get_mpf()->get_fileid(fileid);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
throw std::runtime_error(strprintf("CDB: Can't open database %s (get_fileid failed with %d)", filename, ret));
|
throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (get_fileid failed with %d)", filename, ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& item : env.mapDb) {
|
for (const auto& item : env.mapDb) {
|
||||||
|
@ -46,7 +46,7 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db)
|
||||||
memcmp(fileid, item_fileid, sizeof(fileid)) == 0) {
|
memcmp(fileid, item_fileid, sizeof(fileid)) == 0) {
|
||||||
const char* item_filename = nullptr;
|
const char* item_filename = nullptr;
|
||||||
item.second->get_dbname(&item_filename, nullptr);
|
item.second->get_dbname(&item_filename, nullptr);
|
||||||
throw std::runtime_error(strprintf("CDB: Can't open database %s (duplicates fileid %s from %s)", filename,
|
throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (duplicates fileid %s from %s)", filename,
|
||||||
HexStr(std::begin(item_fileid), std::end(item_fileid)),
|
HexStr(std::begin(item_fileid), std::end(item_fileid)),
|
||||||
item_filename ? item_filename : "(unknown database)"));
|
item_filename ? item_filename : "(unknown database)"));
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,10 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db)
|
||||||
}
|
}
|
||||||
|
|
||||||
CCriticalSection cs_db;
|
CCriticalSection cs_db;
|
||||||
std::map<std::string, CDBEnv> g_dbenvs; //!< Map from directory name to open db environment.
|
std::map<std::string, BerkeleyEnvironment> g_dbenvs; //!< Map from directory name to open db environment.
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename)
|
BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename)
|
||||||
{
|
{
|
||||||
fs::path env_directory;
|
fs::path env_directory;
|
||||||
if (fs::is_regular_file(wallet_path)) {
|
if (fs::is_regular_file(wallet_path)) {
|
||||||
|
@ -73,7 +73,7 @@ CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename
|
||||||
database_filename = "wallet.dat";
|
database_filename = "wallet.dat";
|
||||||
}
|
}
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
// Note: An ununsed temporary CDBEnv object may be created inside the
|
// Note: An ununsed temporary BerkeleyEnvironment object may be created inside the
|
||||||
// emplace function if the key already exists. This is a little inefficient,
|
// emplace function if the key already exists. This is a little inefficient,
|
||||||
// but not a big concern since the map will be changed in the future to hold
|
// but not a big concern since the map will be changed in the future to hold
|
||||||
// pointers instead of objects, anyway.
|
// pointers instead of objects, anyway.
|
||||||
|
@ -81,10 +81,10 @@ CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// CDB
|
// BerkeleyBatch
|
||||||
//
|
//
|
||||||
|
|
||||||
void CDBEnv::Close()
|
void BerkeleyEnvironment::Close()
|
||||||
{
|
{
|
||||||
if (!fDbEnvInit)
|
if (!fDbEnvInit)
|
||||||
return;
|
return;
|
||||||
|
@ -103,29 +103,29 @@ void CDBEnv::Close()
|
||||||
|
|
||||||
int ret = dbenv->close(0);
|
int ret = dbenv->close(0);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
|
LogPrintf("BerkeleyEnvironment::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret));
|
||||||
if (!fMockDb)
|
if (!fMockDb)
|
||||||
DbEnv((u_int32_t)0).remove(strPath.c_str(), 0);
|
DbEnv((u_int32_t)0).remove(strPath.c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDBEnv::Reset()
|
void BerkeleyEnvironment::Reset()
|
||||||
{
|
{
|
||||||
dbenv.reset(new DbEnv(DB_CXX_NO_EXCEPTIONS));
|
dbenv.reset(new DbEnv(DB_CXX_NO_EXCEPTIONS));
|
||||||
fDbEnvInit = false;
|
fDbEnvInit = false;
|
||||||
fMockDb = false;
|
fMockDb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDBEnv::CDBEnv(const fs::path& dir_path) : strPath(dir_path.string())
|
BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(dir_path.string())
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
CDBEnv::~CDBEnv()
|
BerkeleyEnvironment::~BerkeleyEnvironment()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDBEnv::Open(bool retry)
|
bool BerkeleyEnvironment::Open(bool retry)
|
||||||
{
|
{
|
||||||
if (fDbEnvInit)
|
if (fDbEnvInit)
|
||||||
return true;
|
return true;
|
||||||
|
@ -142,7 +142,7 @@ bool CDBEnv::Open(bool retry)
|
||||||
fs::path pathLogDir = pathIn / "database";
|
fs::path pathLogDir = pathIn / "database";
|
||||||
TryCreateDirectories(pathLogDir);
|
TryCreateDirectories(pathLogDir);
|
||||||
fs::path pathErrorFile = pathIn / "db.log";
|
fs::path pathErrorFile = pathIn / "db.log";
|
||||||
LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
|
LogPrintf("BerkeleyEnvironment::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());
|
||||||
|
|
||||||
unsigned int nEnvFlags = 0;
|
unsigned int nEnvFlags = 0;
|
||||||
if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB))
|
if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB))
|
||||||
|
@ -170,7 +170,7 @@ bool CDBEnv::Open(bool retry)
|
||||||
S_IRUSR | S_IWUSR);
|
S_IRUSR | S_IWUSR);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
dbenv->close(0);
|
dbenv->close(0);
|
||||||
LogPrintf("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
|
LogPrintf("BerkeleyEnvironment::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret));
|
||||||
if (retry) {
|
if (retry) {
|
||||||
// try moving the database env out of the way
|
// try moving the database env out of the way
|
||||||
fs::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime());
|
fs::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime());
|
||||||
|
@ -195,14 +195,14 @@ bool CDBEnv::Open(bool retry)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDBEnv::MakeMock()
|
void BerkeleyEnvironment::MakeMock()
|
||||||
{
|
{
|
||||||
if (fDbEnvInit)
|
if (fDbEnvInit)
|
||||||
throw std::runtime_error("CDBEnv::MakeMock: Already initialized");
|
throw std::runtime_error("BerkeleyEnvironment::MakeMock: Already initialized");
|
||||||
|
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
LogPrint(BCLog::DB, "CDBEnv::MakeMock\n");
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::MakeMock\n");
|
||||||
|
|
||||||
dbenv->set_cachesize(1, 0, 1);
|
dbenv->set_cachesize(1, 0, 1);
|
||||||
dbenv->set_lg_bsize(10485760 * 4);
|
dbenv->set_lg_bsize(10485760 * 4);
|
||||||
|
@ -221,13 +221,13 @@ void CDBEnv::MakeMock()
|
||||||
DB_PRIVATE,
|
DB_PRIVATE,
|
||||||
S_IRUSR | S_IWUSR);
|
S_IRUSR | S_IWUSR);
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
throw std::runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret));
|
throw std::runtime_error(strprintf("BerkeleyEnvironment::MakeMock: Error %d opening database environment.", ret));
|
||||||
|
|
||||||
fDbEnvInit = true;
|
fDbEnvInit = true;
|
||||||
fMockDb = true;
|
fMockDb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename)
|
BerkeleyEnvironment::VerifyResult BerkeleyEnvironment::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename)
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
assert(mapFileUseCount.count(strFile) == 0);
|
assert(mapFileUseCount.count(strFile) == 0);
|
||||||
|
@ -244,10 +244,10 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type
|
||||||
return (fRecovered ? VerifyResult::RECOVER_OK : VerifyResult::RECOVER_FAIL);
|
return (fRecovered ? VerifyResult::RECOVER_OK : VerifyResult::RECOVER_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
|
bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
|
||||||
{
|
{
|
||||||
std::string filename;
|
std::string filename;
|
||||||
CDBEnv* env = GetWalletEnv(file_path, filename);
|
BerkeleyEnvironment* env = GetWalletEnv(file_path, filename);
|
||||||
|
|
||||||
// Recovery procedure:
|
// Recovery procedure:
|
||||||
// move wallet file to walletfilename.timestamp.bak
|
// move wallet file to walletfilename.timestamp.bak
|
||||||
|
@ -269,7 +269,7 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CDBEnv::KeyValPair> salvagedData;
|
std::vector<BerkeleyEnvironment::KeyValPair> salvagedData;
|
||||||
bool fSuccess = env->Salvage(newFilename, true, salvagedData);
|
bool fSuccess = env->Salvage(newFilename, true, salvagedData);
|
||||||
if (salvagedData.empty())
|
if (salvagedData.empty())
|
||||||
{
|
{
|
||||||
|
@ -292,7 +292,7 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove
|
||||||
}
|
}
|
||||||
|
|
||||||
DbTxn* ptxn = env->TxnBegin();
|
DbTxn* ptxn = env->TxnBegin();
|
||||||
for (CDBEnv::KeyValPair& row : salvagedData)
|
for (BerkeleyEnvironment::KeyValPair& row : salvagedData)
|
||||||
{
|
{
|
||||||
if (recoverKVcallback)
|
if (recoverKVcallback)
|
||||||
{
|
{
|
||||||
|
@ -313,10 +313,10 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove
|
||||||
return fSuccess;
|
return fSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDB::VerifyEnvironment(const fs::path& file_path, std::string& errorStr)
|
bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& errorStr)
|
||||||
{
|
{
|
||||||
std::string walletFile;
|
std::string walletFile;
|
||||||
CDBEnv* env = GetWalletEnv(file_path, walletFile);
|
BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile);
|
||||||
fs::path walletDir = env->Directory();
|
fs::path walletDir = env->Directory();
|
||||||
|
|
||||||
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
||||||
|
@ -337,17 +337,17 @@ bool CDB::VerifyEnvironment(const fs::path& file_path, std::string& errorStr)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc)
|
bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
|
||||||
{
|
{
|
||||||
std::string walletFile;
|
std::string walletFile;
|
||||||
CDBEnv* env = GetWalletEnv(file_path, walletFile);
|
BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile);
|
||||||
fs::path walletDir = env->Directory();
|
fs::path walletDir = env->Directory();
|
||||||
|
|
||||||
if (fs::exists(walletDir / walletFile))
|
if (fs::exists(walletDir / walletFile))
|
||||||
{
|
{
|
||||||
std::string backup_filename;
|
std::string backup_filename;
|
||||||
CDBEnv::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename);
|
BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename);
|
||||||
if (r == CDBEnv::VerifyResult::RECOVER_OK)
|
if (r == BerkeleyEnvironment::VerifyResult::RECOVER_OK)
|
||||||
{
|
{
|
||||||
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
|
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
|
||||||
" Original %s saved as %s in %s; if"
|
" Original %s saved as %s in %s; if"
|
||||||
|
@ -355,7 +355,7 @@ bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr,
|
||||||
" restore from a backup."),
|
" restore from a backup."),
|
||||||
walletFile, backup_filename, walletDir);
|
walletFile, backup_filename, walletDir);
|
||||||
}
|
}
|
||||||
if (r == CDBEnv::VerifyResult::RECOVER_FAIL)
|
if (r == BerkeleyEnvironment::VerifyResult::RECOVER_FAIL)
|
||||||
{
|
{
|
||||||
errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile);
|
errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile);
|
||||||
return false;
|
return false;
|
||||||
|
@ -370,7 +370,7 @@ static const char *HEADER_END = "HEADER=END";
|
||||||
/* End of key/value data */
|
/* End of key/value data */
|
||||||
static const char *DATA_END = "DATA=END";
|
static const char *DATA_END = "DATA=END";
|
||||||
|
|
||||||
bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult)
|
bool BerkeleyEnvironment::Salvage(const std::string& strFile, bool fAggressive, std::vector<BerkeleyEnvironment::KeyValPair>& vResult)
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
assert(mapFileUseCount.count(strFile) == 0);
|
assert(mapFileUseCount.count(strFile) == 0);
|
||||||
|
@ -384,14 +384,14 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
|
||||||
Db db(dbenv.get(), 0);
|
Db db(dbenv.get(), 0);
|
||||||
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags);
|
int result = db.verify(strFile.c_str(), nullptr, &strDump, flags);
|
||||||
if (result == DB_VERIFY_BAD) {
|
if (result == DB_VERIFY_BAD) {
|
||||||
LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n");
|
LogPrintf("BerkeleyEnvironment::Salvage: Database salvage found errors, all data may not be recoverable.\n");
|
||||||
if (!fAggressive) {
|
if (!fAggressive) {
|
||||||
LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore errors and continue.\n");
|
LogPrintf("BerkeleyEnvironment::Salvage: Rerun with aggressive mode to ignore errors and continue.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result != 0 && result != DB_VERIFY_BAD) {
|
if (result != 0 && result != DB_VERIFY_BAD) {
|
||||||
LogPrintf("CDBEnv::Salvage: Database salvage failed with result %d.\n", result);
|
LogPrintf("BerkeleyEnvironment::Salvage: Database salvage failed with result %d.\n", result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
|
||||||
break;
|
break;
|
||||||
getline(strDump, valueHex);
|
getline(strDump, valueHex);
|
||||||
if (valueHex == DATA_END) {
|
if (valueHex == DATA_END) {
|
||||||
LogPrintf("CDBEnv::Salvage: WARNING: Number of keys in data does not match number of values.\n");
|
LogPrintf("BerkeleyEnvironment::Salvage: WARNING: Number of keys in data does not match number of values.\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
|
vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
|
||||||
|
@ -423,7 +423,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyHex != DATA_END) {
|
if (keyHex != DATA_END) {
|
||||||
LogPrintf("CDBEnv::Salvage: WARNING: Unexpected end of file while reading salvage output.\n");
|
LogPrintf("BerkeleyEnvironment::Salvage: WARNING: Unexpected end of file while reading salvage output.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDBEnv::CheckpointLSN(const std::string& strFile)
|
void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile)
|
||||||
{
|
{
|
||||||
dbenv->txn_checkpoint(0, 0, 0);
|
dbenv->txn_checkpoint(0, 0, 0);
|
||||||
if (fMockDb)
|
if (fMockDb)
|
||||||
|
@ -440,15 +440,15 @@ void CDBEnv::CheckpointLSN(const std::string& strFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr)
|
BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr)
|
||||||
{
|
{
|
||||||
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||||
fFlushOnClose = fFlushOnCloseIn;
|
fFlushOnClose = fFlushOnCloseIn;
|
||||||
env = dbw.env;
|
env = database.env;
|
||||||
if (dbw.IsDummy()) {
|
if (database.IsDummy()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const std::string &strFilename = dbw.strFile;
|
const std::string &strFilename = database.strFile;
|
||||||
|
|
||||||
bool fCreate = strchr(pszMode, 'c') != nullptr;
|
bool fCreate = strchr(pszMode, 'c') != nullptr;
|
||||||
unsigned int nFlags = DB_THREAD;
|
unsigned int nFlags = DB_THREAD;
|
||||||
|
@ -458,7 +458,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
if (!env->Open(false /* retry */))
|
if (!env->Open(false /* retry */))
|
||||||
throw std::runtime_error("CDB: Failed to open database environment.");
|
throw std::runtime_error("BerkeleyBatch: Failed to open database environment.");
|
||||||
|
|
||||||
pdb = env->mapDb[strFilename];
|
pdb = env->mapDb[strFilename];
|
||||||
if (pdb == nullptr) {
|
if (pdb == nullptr) {
|
||||||
|
@ -470,7 +470,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
||||||
DbMpoolFile* mpf = pdb_temp->get_mpf();
|
DbMpoolFile* mpf = pdb_temp->get_mpf();
|
||||||
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
|
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFilename));
|
throw std::runtime_error(strprintf("BerkeleyBatch: Failed to configure for no temp file backing for database %s", strFilename));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,7 +482,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
||||||
0);
|
0);
|
||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
|
throw std::runtime_error(strprintf("BerkeleyBatch: Error %d, can't open database %s", ret, strFilename));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call CheckUniqueFileid on the containing BDB environment to
|
// Call CheckUniqueFileid on the containing BDB environment to
|
||||||
|
@ -519,7 +519,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDB::Flush()
|
void BerkeleyBatch::Flush()
|
||||||
{
|
{
|
||||||
if (activeTxn)
|
if (activeTxn)
|
||||||
return;
|
return;
|
||||||
|
@ -532,12 +532,12 @@ void CDB::Flush()
|
||||||
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
|
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWalletDBWrapper::IncrementUpdateCounter()
|
void BerkeleyDatabase::IncrementUpdateCounter()
|
||||||
{
|
{
|
||||||
++nUpdateCounter;
|
++nUpdateCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDB::Close()
|
void BerkeleyBatch::Close()
|
||||||
{
|
{
|
||||||
if (!pdb)
|
if (!pdb)
|
||||||
return;
|
return;
|
||||||
|
@ -555,7 +555,7 @@ void CDB::Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDBEnv::CloseDb(const std::string& strFile)
|
void BerkeleyEnvironment::CloseDb(const std::string& strFile)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
|
@ -569,13 +569,13 @@ void CDBEnv::CloseDb(const std::string& strFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
|
||||||
{
|
{
|
||||||
if (dbw.IsDummy()) {
|
if (database.IsDummy()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
CDBEnv *env = dbw.env;
|
BerkeleyEnvironment *env = database.env;
|
||||||
const std::string& strFile = dbw.strFile;
|
const std::string& strFile = database.strFile;
|
||||||
while (true) {
|
while (true) {
|
||||||
{
|
{
|
||||||
LOCK(cs_db);
|
LOCK(cs_db);
|
||||||
|
@ -586,10 +586,10 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
||||||
env->mapFileUseCount.erase(strFile);
|
env->mapFileUseCount.erase(strFile);
|
||||||
|
|
||||||
bool fSuccess = true;
|
bool fSuccess = true;
|
||||||
LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
|
LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile);
|
||||||
std::string strFileRes = strFile + ".rewrite";
|
std::string strFileRes = strFile + ".rewrite";
|
||||||
{ // surround usage of db with extra {}
|
{ // surround usage of db with extra {}
|
||||||
CDB db(dbw, "r");
|
BerkeleyBatch db(database, "r");
|
||||||
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
|
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
|
||||||
|
|
||||||
int ret = pdbCopy->open(nullptr, // Txn pointer
|
int ret = pdbCopy->open(nullptr, // Txn pointer
|
||||||
|
@ -599,7 +599,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
||||||
DB_CREATE, // Flags
|
DB_CREATE, // Flags
|
||||||
0);
|
0);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes);
|
LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes);
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,7 +649,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
||||||
fSuccess = false;
|
fSuccess = false;
|
||||||
}
|
}
|
||||||
if (!fSuccess)
|
if (!fSuccess)
|
||||||
LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes);
|
LogPrintf("BerkeleyBatch::Rewrite: Failed to rewrite database file %s\n", strFileRes);
|
||||||
return fSuccess;
|
return fSuccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,11 +658,11 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CDBEnv::Flush(bool fShutdown)
|
void BerkeleyEnvironment::Flush(bool fShutdown)
|
||||||
{
|
{
|
||||||
int64_t nStart = GetTimeMillis();
|
int64_t nStart = GetTimeMillis();
|
||||||
// Flush log data to the actual data file on all files that are not in use
|
// Flush log data to the actual data file on all files that are not in use
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started");
|
||||||
if (!fDbEnvInit)
|
if (!fDbEnvInit)
|
||||||
return;
|
return;
|
||||||
{
|
{
|
||||||
|
@ -671,21 +671,21 @@ void CDBEnv::Flush(bool fShutdown)
|
||||||
while (mi != mapFileUseCount.end()) {
|
while (mi != mapFileUseCount.end()) {
|
||||||
std::string strFile = (*mi).first;
|
std::string strFile = (*mi).first;
|
||||||
int nRefCount = (*mi).second;
|
int nRefCount = (*mi).second;
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount);
|
||||||
if (nRefCount == 0) {
|
if (nRefCount == 0) {
|
||||||
// Move log data to the dat file
|
// Move log data to the dat file
|
||||||
CloseDb(strFile);
|
CloseDb(strFile);
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: %s checkpoint\n", strFile);
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s checkpoint\n", strFile);
|
||||||
dbenv->txn_checkpoint(0, 0, 0);
|
dbenv->txn_checkpoint(0, 0, 0);
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: %s detach\n", strFile);
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s detach\n", strFile);
|
||||||
if (!fMockDb)
|
if (!fMockDb)
|
||||||
dbenv->lsn_reset(strFile.c_str(), 0);
|
dbenv->lsn_reset(strFile.c_str(), 0);
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: %s closed\n", strFile);
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s closed\n", strFile);
|
||||||
mapFileUseCount.erase(mi++);
|
mapFileUseCount.erase(mi++);
|
||||||
} else
|
} else
|
||||||
mi++;
|
mi++;
|
||||||
}
|
}
|
||||||
LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
|
LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart);
|
||||||
if (fShutdown) {
|
if (fShutdown) {
|
||||||
char** listp;
|
char** listp;
|
||||||
if (mapFileUseCount.empty()) {
|
if (mapFileUseCount.empty()) {
|
||||||
|
@ -698,14 +698,14 @@ void CDBEnv::Flush(bool fShutdown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
|
bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase& database)
|
||||||
{
|
{
|
||||||
if (dbw.IsDummy()) {
|
if (database.IsDummy()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
CDBEnv *env = dbw.env;
|
BerkeleyEnvironment *env = database.env;
|
||||||
const std::string& strFile = dbw.strFile;
|
const std::string& strFile = database.strFile;
|
||||||
TRY_LOCK(cs_db, lockDb);
|
TRY_LOCK(cs_db, lockDb);
|
||||||
if (lockDb)
|
if (lockDb)
|
||||||
{
|
{
|
||||||
|
@ -741,12 +741,12 @@ bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDBWrapper::Rewrite(const char* pszSkip)
|
bool BerkeleyDatabase::Rewrite(const char* pszSkip)
|
||||||
{
|
{
|
||||||
return CDB::Rewrite(*this, pszSkip);
|
return BerkeleyBatch::Rewrite(*this, pszSkip);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDBWrapper::Backup(const std::string& strDest)
|
bool BerkeleyDatabase::Backup(const std::string& strDest)
|
||||||
{
|
{
|
||||||
if (IsDummy()) {
|
if (IsDummy()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -787,7 +787,7 @@ bool CWalletDBWrapper::Backup(const std::string& strDest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWalletDBWrapper::Flush(bool shutdown)
|
void BerkeleyDatabase::Flush(bool shutdown)
|
||||||
{
|
{
|
||||||
if (!IsDummy()) {
|
if (!IsDummy()) {
|
||||||
env->Flush(shutdown);
|
env->Flush(shutdown);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
|
static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
|
||||||
static const bool DEFAULT_WALLET_PRIVDB = true;
|
static const bool DEFAULT_WALLET_PRIVDB = true;
|
||||||
|
|
||||||
class CDBEnv
|
class BerkeleyEnvironment
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool fDbEnvInit;
|
bool fDbEnvInit;
|
||||||
|
@ -39,8 +39,8 @@ public:
|
||||||
std::map<std::string, int> mapFileUseCount;
|
std::map<std::string, int> mapFileUseCount;
|
||||||
std::map<std::string, Db*> mapDb;
|
std::map<std::string, Db*> mapDb;
|
||||||
|
|
||||||
CDBEnv(const fs::path& env_directory);
|
BerkeleyEnvironment(const fs::path& env_directory);
|
||||||
~CDBEnv();
|
~BerkeleyEnvironment();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
void MakeMock();
|
void MakeMock();
|
||||||
|
@ -86,23 +86,23 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Get CDBEnv and database filename given a wallet path. */
|
/** Get BerkeleyEnvironment and database filename given a wallet path. */
|
||||||
CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
|
BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
|
||||||
|
|
||||||
/** An instance of this class represents one database.
|
/** An instance of this class represents one database.
|
||||||
* For BerkeleyDB this is just a (env, strFile) tuple.
|
* For BerkeleyDB this is just a (env, strFile) tuple.
|
||||||
**/
|
**/
|
||||||
class CWalletDBWrapper
|
class BerkeleyDatabase
|
||||||
{
|
{
|
||||||
friend class CDB;
|
friend class BerkeleyBatch;
|
||||||
public:
|
public:
|
||||||
/** Create dummy DB handle */
|
/** Create dummy DB handle */
|
||||||
CWalletDBWrapper() : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr)
|
BerkeleyDatabase() : nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create DB handle to real database */
|
/** Create DB handle to real database */
|
||||||
CWalletDBWrapper(const fs::path& wallet_path, bool mock = false) :
|
BerkeleyDatabase(const fs::path& wallet_path, bool mock = false) :
|
||||||
nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0)
|
nUpdateCounter(0), nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0)
|
||||||
{
|
{
|
||||||
env = GetWalletEnv(wallet_path, strFile);
|
env = GetWalletEnv(wallet_path, strFile);
|
||||||
|
@ -114,21 +114,21 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return object for accessing database at specified path. */
|
/** Return object for accessing database at specified path. */
|
||||||
static std::unique_ptr<CWalletDBWrapper> Create(const fs::path& path)
|
static std::unique_ptr<BerkeleyDatabase> Create(const fs::path& path)
|
||||||
{
|
{
|
||||||
return MakeUnique<CWalletDBWrapper>(path);
|
return MakeUnique<BerkeleyDatabase>(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return object for accessing dummy database with no read/write capabilities. */
|
/** Return object for accessing dummy database with no read/write capabilities. */
|
||||||
static std::unique_ptr<CWalletDBWrapper> CreateDummy()
|
static std::unique_ptr<BerkeleyDatabase> CreateDummy()
|
||||||
{
|
{
|
||||||
return MakeUnique<CWalletDBWrapper>();
|
return MakeUnique<BerkeleyDatabase>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return object for accessing temporary in-memory database. */
|
/** Return object for accessing temporary in-memory database. */
|
||||||
static std::unique_ptr<CWalletDBWrapper> CreateMock()
|
static std::unique_ptr<BerkeleyDatabase> CreateMock()
|
||||||
{
|
{
|
||||||
return MakeUnique<CWalletDBWrapper>("", true /* mock */);
|
return MakeUnique<BerkeleyDatabase>("", true /* mock */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
|
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
|
||||||
|
@ -152,7 +152,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** BerkeleyDB specific */
|
/** BerkeleyDB specific */
|
||||||
CDBEnv *env;
|
BerkeleyEnvironment *env;
|
||||||
std::string strFile;
|
std::string strFile;
|
||||||
|
|
||||||
/** Return whether this database handle is a dummy for testing.
|
/** Return whether this database handle is a dummy for testing.
|
||||||
|
@ -164,7 +164,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
/** RAII class that provides access to a Berkeley database */
|
/** RAII class that provides access to a Berkeley database */
|
||||||
class CDB
|
class BerkeleyBatch
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Db* pdb;
|
Db* pdb;
|
||||||
|
@ -172,14 +172,14 @@ protected:
|
||||||
DbTxn* activeTxn;
|
DbTxn* activeTxn;
|
||||||
bool fReadOnly;
|
bool fReadOnly;
|
||||||
bool fFlushOnClose;
|
bool fFlushOnClose;
|
||||||
CDBEnv *env;
|
BerkeleyEnvironment *env;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
|
explicit BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
|
||||||
~CDB() { Close(); }
|
~BerkeleyBatch() { Close(); }
|
||||||
|
|
||||||
CDB(const CDB&) = delete;
|
BerkeleyBatch(const BerkeleyBatch&) = delete;
|
||||||
CDB& operator=(const CDB&) = delete;
|
BerkeleyBatch& operator=(const BerkeleyBatch&) = delete;
|
||||||
|
|
||||||
void Flush();
|
void Flush();
|
||||||
void Close();
|
void Close();
|
||||||
|
@ -187,11 +187,11 @@ public:
|
||||||
|
|
||||||
/* flush the wallet passively (TRY_LOCK)
|
/* flush the wallet passively (TRY_LOCK)
|
||||||
ideal to be called periodically */
|
ideal to be called periodically */
|
||||||
static bool PeriodicFlush(CWalletDBWrapper& dbw);
|
static bool PeriodicFlush(BerkeleyDatabase& database);
|
||||||
/* verifies the database environment */
|
/* verifies the database environment */
|
||||||
static bool VerifyEnvironment(const fs::path& file_path, std::string& errorStr);
|
static bool VerifyEnvironment(const fs::path& file_path, std::string& errorStr);
|
||||||
/* verifies the database file */
|
/* verifies the database file */
|
||||||
static bool VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc);
|
static bool VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename K, typename T>
|
template <typename K, typename T>
|
||||||
|
@ -387,7 +387,7 @@ public:
|
||||||
return Write(std::string("version"), nVersion);
|
return Write(std::string("version"), nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool static Rewrite(CWalletDBWrapper& dbw, const char* pszSkip = nullptr);
|
bool static Rewrite(BerkeleyDatabase& database, const char* pszSkip = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_WALLET_DB_H
|
#endif // BITCOIN_WALLET_DB_H
|
||||||
|
|
|
@ -277,21 +277,21 @@ bool WalletInit::Verify()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strError;
|
std::string strError;
|
||||||
if (!CWalletDB::VerifyEnvironment(wallet_path, strError)) {
|
if (!WalletBatch::VerifyEnvironment(wallet_path, strError)) {
|
||||||
return InitError(strError);
|
return InitError(strError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gArgs.GetBoolArg("-salvagewallet", false)) {
|
if (gArgs.GetBoolArg("-salvagewallet", false)) {
|
||||||
// Recover readable keypairs:
|
// Recover readable keypairs:
|
||||||
CWallet dummyWallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet dummyWallet("dummy", WalletDatabase::CreateDummy());
|
||||||
std::string backup_filename;
|
std::string backup_filename;
|
||||||
if (!CWalletDB::Recover(wallet_path, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) {
|
if (!WalletBatch::Recover(wallet_path, (void *)&dummyWallet, WalletBatch::RecoverKeysOnlyFilter, backup_filename)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strWarning;
|
std::string strWarning;
|
||||||
bool dbV = CWalletDB::VerifyDatabaseFile(wallet_path, strWarning, strError);
|
bool dbV = WalletBatch::VerifyDatabaseFile(wallet_path, strWarning, strError);
|
||||||
if (!strWarning.empty()) {
|
if (!strWarning.empty()) {
|
||||||
InitWarning(strWarning);
|
InitWarning(strWarning);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ std::vector<std::unique_ptr<CWalletTx>> wtxn;
|
||||||
typedef std::set<CInputCoin> CoinSet;
|
typedef std::set<CInputCoin> CoinSet;
|
||||||
|
|
||||||
static std::vector<COutput> vCoins;
|
static std::vector<COutput> vCoins;
|
||||||
static CWallet testWallet("dummy", CWalletDBWrapper::CreateDummy());
|
static CWallet testWallet("dummy", WalletDatabase::CreateDummy());
|
||||||
static CAmount balance = 0;
|
static CAmount balance = 0;
|
||||||
|
|
||||||
CoinEligibilityFilter filter_standard(1, 6, 0);
|
CoinEligibilityFilter filter_standard(1, 6, 0);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
||||||
TestingSetup(chainName), m_wallet("mock", CWalletDBWrapper::CreateMock())
|
TestingSetup(chainName), m_wallet("mock", WalletDatabase::CreateMock())
|
||||||
{
|
{
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
m_wallet.LoadWallet(fFirstRun);
|
m_wallet.LoadWallet(fFirstRun);
|
||||||
|
|
|
@ -46,7 +46,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
// Verify ScanForWalletTransactions picks up transactions in both the old
|
// Verify ScanForWalletTransactions picks up transactions in both the old
|
||||||
// and new block files.
|
// and new block files.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
AddKey(wallet, coinbaseKey);
|
AddKey(wallet, coinbaseKey);
|
||||||
WalletRescanReserver reserver(&wallet);
|
WalletRescanReserver reserver(&wallet);
|
||||||
reserver.reserve();
|
reserver.reserve();
|
||||||
|
@ -61,7 +61,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
// Verify ScanForWalletTransactions only picks transactions in the new block
|
// Verify ScanForWalletTransactions only picks transactions in the new block
|
||||||
// file.
|
// file.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
AddKey(wallet, coinbaseKey);
|
AddKey(wallet, coinbaseKey);
|
||||||
WalletRescanReserver reserver(&wallet);
|
WalletRescanReserver reserver(&wallet);
|
||||||
reserver.reserve();
|
reserver.reserve();
|
||||||
|
@ -73,7 +73,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
// before the missing block, and success for a key whose creation time is
|
// before the missing block, and success for a key whose creation time is
|
||||||
// after.
|
// after.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
vpwallets.insert(vpwallets.begin(), &wallet);
|
||||||
UniValue keys;
|
UniValue keys;
|
||||||
keys.setArray();
|
keys.setArray();
|
||||||
|
@ -132,7 +132,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
|
|
||||||
// Import key into wallet and call dumpwallet to create backup file.
|
// Import key into wallet and call dumpwallet to create backup file.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
wallet.mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
|
wallet.mapKeyMetadata[coinbaseKey.GetPubKey().GetID()].nCreateTime = KEY_TIME;
|
||||||
wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
|
wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey());
|
||||||
|
@ -147,7 +147,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
|
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
|
||||||
// were scanned, and no prior blocks were scanned.
|
// were scanned, and no prior blocks were scanned.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
|
|
||||||
JSONRPCRequest request;
|
JSONRPCRequest request;
|
||||||
request.params.setArray();
|
request.params.setArray();
|
||||||
|
@ -177,7 +177,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
// debit functions.
|
// debit functions.
|
||||||
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
|
BOOST_FIXTURE_TEST_CASE(coin_mark_dirty_immature_credit, TestChain100Setup)
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", CWalletDBWrapper::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
CWalletTx wtx(&wallet, MakeTransactionRef(coinbaseTxns.back()));
|
CWalletTx wtx(&wallet, MakeTransactionRef(coinbaseTxns.back()));
|
||||||
LOCK2(cs_main, wallet.cs_wallet);
|
LOCK2(cs_main, wallet.cs_wallet);
|
||||||
wtx.hashBlock = chainActive.Tip()->GetBlockHash();
|
wtx.hashBlock = chainActive.Tip()->GetBlockHash();
|
||||||
|
@ -270,7 +270,7 @@ public:
|
||||||
ListCoinsTestingSetup()
|
ListCoinsTestingSetup()
|
||||||
{
|
{
|
||||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
||||||
wallet = MakeUnique<CWallet>("mock", CWalletDBWrapper::CreateMock());
|
wallet = MakeUnique<CWallet>("mock", WalletDatabase::CreateMock());
|
||||||
bool firstRun;
|
bool firstRun;
|
||||||
wallet->LoadWallet(firstRun);
|
wallet->LoadWallet(firstRun);
|
||||||
AddKey(*wallet, coinbaseKey);
|
AddKey(*wallet, coinbaseKey);
|
||||||
|
|
|
@ -131,7 +131,7 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
|
||||||
return &(it->second);
|
return &(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
|
CPubKey CWallet::GenerateNewKey(WalletBatch &batch, bool internal)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
|
||||||
|
@ -144,7 +144,7 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
|
||||||
|
|
||||||
// use HD key derivation if HD was enabled during wallet creation
|
// use HD key derivation if HD was enabled during wallet creation
|
||||||
if (IsHDEnabled()) {
|
if (IsHDEnabled()) {
|
||||||
DeriveNewChildKey(walletdb, metadata, secret, (CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
|
DeriveNewChildKey(batch, metadata, secret, (CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
|
||||||
} else {
|
} else {
|
||||||
secret.MakeNewKey(fCompressed);
|
secret.MakeNewKey(fCompressed);
|
||||||
}
|
}
|
||||||
|
@ -160,13 +160,13 @@ CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
|
||||||
mapKeyMetadata[pubkey.GetID()] = metadata;
|
mapKeyMetadata[pubkey.GetID()] = metadata;
|
||||||
UpdateTimeFirstKey(nCreationTime);
|
UpdateTimeFirstKey(nCreationTime);
|
||||||
|
|
||||||
if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
|
if (!AddKeyPubKeyWithDB(batch, secret, pubkey)) {
|
||||||
throw std::runtime_error(std::string(__func__) + ": AddKey failed");
|
throw std::runtime_error(std::string(__func__) + ": AddKey failed");
|
||||||
}
|
}
|
||||||
return pubkey;
|
return pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKey& secret, bool internal)
|
void CWallet::DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, bool internal)
|
||||||
{
|
{
|
||||||
// for now we use a fixed keypath scheme of m/0'/0'/k
|
// for now we use a fixed keypath scheme of m/0'/0'/k
|
||||||
CKey key; //master key seed (256bit)
|
CKey key; //master key seed (256bit)
|
||||||
|
@ -208,26 +208,26 @@ void CWallet::DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKe
|
||||||
secret = childKey.key;
|
secret = childKey.key;
|
||||||
metadata.hdMasterKeyID = hdChain.masterKeyID;
|
metadata.hdMasterKeyID = hdChain.masterKeyID;
|
||||||
// update the chain model in the database
|
// update the chain model in the database
|
||||||
if (!walletdb.WriteHDChain(hdChain))
|
if (!batch.WriteHDChain(hdChain))
|
||||||
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
|
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const CPubKey &pubkey)
|
bool CWallet::AddKeyPubKeyWithDB(WalletBatch &batch, const CKey& secret, const CPubKey &pubkey)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
|
|
||||||
// CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
|
// CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
|
||||||
// which is overridden below. To avoid flushes, the database handle is
|
// which is overridden below. To avoid flushes, the database handle is
|
||||||
// tunneled through to it.
|
// tunneled through to it.
|
||||||
bool needsDB = !pwalletdbEncryption;
|
bool needsDB = !encrypted_batch;
|
||||||
if (needsDB) {
|
if (needsDB) {
|
||||||
pwalletdbEncryption = &walletdb;
|
encrypted_batch = &batch;
|
||||||
}
|
}
|
||||||
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
|
if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
|
||||||
if (needsDB) pwalletdbEncryption = nullptr;
|
if (needsDB) encrypted_batch = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (needsDB) pwalletdbEncryption = nullptr;
|
if (needsDB) encrypted_batch = nullptr;
|
||||||
|
|
||||||
// check if we need to remove from watch-only
|
// check if we need to remove from watch-only
|
||||||
CScript script;
|
CScript script;
|
||||||
|
@ -241,7 +241,7 @@ bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsCrypted()) {
|
if (!IsCrypted()) {
|
||||||
return walletdb.WriteKey(pubkey,
|
return batch.WriteKey(pubkey,
|
||||||
secret.GetPrivKey(),
|
secret.GetPrivKey(),
|
||||||
mapKeyMetadata[pubkey.GetID()]);
|
mapKeyMetadata[pubkey.GetID()]);
|
||||||
}
|
}
|
||||||
|
@ -250,8 +250,8 @@ bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const
|
||||||
|
|
||||||
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
return CWallet::AddKeyPubKeyWithDB(walletdb, secret, pubkey);
|
return CWallet::AddKeyPubKeyWithDB(batch, secret, pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||||
|
@ -261,12 +261,12 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||||
return false;
|
return false;
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
if (pwalletdbEncryption)
|
if (encrypted_batch)
|
||||||
return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
|
return encrypted_batch->WriteCryptedKey(vchPubKey,
|
||||||
vchCryptedSecret,
|
vchCryptedSecret,
|
||||||
mapKeyMetadata[vchPubKey.GetID()]);
|
mapKeyMetadata[vchPubKey.GetID()]);
|
||||||
else
|
else
|
||||||
return CWalletDB(*dbw).WriteCryptedKey(vchPubKey,
|
return WalletBatch(*database).WriteCryptedKey(vchPubKey,
|
||||||
vchCryptedSecret,
|
vchCryptedSecret,
|
||||||
mapKeyMetadata[vchPubKey.GetID()]);
|
mapKeyMetadata[vchPubKey.GetID()]);
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ bool CWallet::AddCScript(const CScript& redeemScript)
|
||||||
{
|
{
|
||||||
if (!CCryptoKeyStore::AddCScript(redeemScript))
|
if (!CCryptoKeyStore::AddCScript(redeemScript))
|
||||||
return false;
|
return false;
|
||||||
return CWalletDB(*dbw).WriteCScript(Hash160(redeemScript), redeemScript);
|
return WalletBatch(*database).WriteCScript(Hash160(redeemScript), redeemScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadCScript(const CScript& redeemScript)
|
bool CWallet::LoadCScript(const CScript& redeemScript)
|
||||||
|
@ -339,7 +339,7 @@ bool CWallet::AddWatchOnly(const CScript& dest)
|
||||||
const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
|
const CKeyMetadata& meta = m_script_metadata[CScriptID(dest)];
|
||||||
UpdateTimeFirstKey(meta.nCreateTime);
|
UpdateTimeFirstKey(meta.nCreateTime);
|
||||||
NotifyWatchonlyChanged(true);
|
NotifyWatchonlyChanged(true);
|
||||||
return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
|
return WalletBatch(*database).WriteWatchOnly(dest, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
|
bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
|
||||||
|
@ -355,7 +355,7 @@ bool CWallet::RemoveWatchOnly(const CScript &dest)
|
||||||
return false;
|
return false;
|
||||||
if (!HaveWatchOnly())
|
if (!HaveWatchOnly())
|
||||||
NotifyWatchonlyChanged(false);
|
NotifyWatchonlyChanged(false);
|
||||||
if (!CWalletDB(*dbw).EraseWatchOnly(dest))
|
if (!WalletBatch(*database).EraseWatchOnly(dest))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -421,7 +421,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||||
return false;
|
return false;
|
||||||
if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
|
if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
|
||||||
return false;
|
return false;
|
||||||
CWalletDB(*dbw).WriteMasterKey(pMasterKey.first, pMasterKey.second);
|
WalletBatch(*database).WriteMasterKey(pMasterKey.first, pMasterKey.second);
|
||||||
if (fWasLocked)
|
if (fWasLocked)
|
||||||
Lock();
|
Lock();
|
||||||
return true;
|
return true;
|
||||||
|
@ -434,11 +434,11 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||||
|
|
||||||
void CWallet::SetBestChain(const CBlockLocator& loc)
|
void CWallet::SetBestChain(const CBlockLocator& loc)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
walletdb.WriteBestBlock(loc);
|
batch.WriteBestBlock(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
|
bool CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in, bool fExplicit)
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet); // nWalletVersion
|
LOCK(cs_wallet); // nWalletVersion
|
||||||
if (nWalletVersion >= nVersion)
|
if (nWalletVersion >= nVersion)
|
||||||
|
@ -454,11 +454,11 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn,
|
||||||
nWalletMaxVersion = nVersion;
|
nWalletMaxVersion = nVersion;
|
||||||
|
|
||||||
{
|
{
|
||||||
CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(*dbw);
|
WalletBatch* batch = batch_in ? batch_in : new WalletBatch(*database);
|
||||||
if (nWalletVersion > 40000)
|
if (nWalletVersion > 40000)
|
||||||
pwalletdb->WriteMinVersion(nWalletVersion);
|
batch->WriteMinVersion(nWalletVersion);
|
||||||
if (!pwalletdbIn)
|
if (!batch_in)
|
||||||
delete pwalletdb;
|
delete batch;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -508,7 +508,7 @@ bool CWallet::HasWalletSpend(const uint256& txid) const
|
||||||
|
|
||||||
void CWallet::Flush(bool shutdown)
|
void CWallet::Flush(bool shutdown)
|
||||||
{
|
{
|
||||||
dbw->Flush(shutdown);
|
database->Flush(shutdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
|
void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
|
||||||
|
@ -631,36 +631,36 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
|
||||||
assert(!pwalletdbEncryption);
|
assert(!encrypted_batch);
|
||||||
pwalletdbEncryption = new CWalletDB(*dbw);
|
encrypted_batch = new WalletBatch(*database);
|
||||||
if (!pwalletdbEncryption->TxnBegin()) {
|
if (!encrypted_batch->TxnBegin()) {
|
||||||
delete pwalletdbEncryption;
|
delete encrypted_batch;
|
||||||
pwalletdbEncryption = nullptr;
|
encrypted_batch = nullptr;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
|
encrypted_batch->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
|
||||||
|
|
||||||
if (!EncryptKeys(_vMasterKey))
|
if (!EncryptKeys(_vMasterKey))
|
||||||
{
|
{
|
||||||
pwalletdbEncryption->TxnAbort();
|
encrypted_batch->TxnAbort();
|
||||||
delete pwalletdbEncryption;
|
delete encrypted_batch;
|
||||||
// We now probably have half of our keys encrypted in memory, and half not...
|
// We now probably have half of our keys encrypted in memory, and half not...
|
||||||
// die and let the user reload the unencrypted wallet.
|
// die and let the user reload the unencrypted wallet.
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encryption was introduced in version 0.4.0
|
// Encryption was introduced in version 0.4.0
|
||||||
SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
|
SetMinVersion(FEATURE_WALLETCRYPT, encrypted_batch, true);
|
||||||
|
|
||||||
if (!pwalletdbEncryption->TxnCommit()) {
|
if (!encrypted_batch->TxnCommit()) {
|
||||||
delete pwalletdbEncryption;
|
delete encrypted_batch;
|
||||||
// We now have keys encrypted in memory, but not on disk...
|
// We now have keys encrypted in memory, but not on disk...
|
||||||
// die to avoid confusion and let the user reload the unencrypted wallet.
|
// die to avoid confusion and let the user reload the unencrypted wallet.
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pwalletdbEncryption;
|
delete encrypted_batch;
|
||||||
pwalletdbEncryption = nullptr;
|
encrypted_batch = nullptr;
|
||||||
|
|
||||||
Lock();
|
Lock();
|
||||||
Unlock(strWalletPassphrase);
|
Unlock(strWalletPassphrase);
|
||||||
|
@ -677,7 +677,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
|
|
||||||
// Need to completely rewrite the wallet file; if we don't, bdb might keep
|
// Need to completely rewrite the wallet file; if we don't, bdb might keep
|
||||||
// bits of the unencrypted private key in slack space in the database file.
|
// bits of the unencrypted private key in slack space in the database file.
|
||||||
dbw->Rewrite();
|
database->Rewrite();
|
||||||
|
|
||||||
}
|
}
|
||||||
NotifyStatusChanged(this);
|
NotifyStatusChanged(this);
|
||||||
|
@ -688,7 +688,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||||
DBErrors CWallet::ReorderTransactions()
|
DBErrors CWallet::ReorderTransactions()
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
// Old wallets didn't have any defined order for transactions
|
// Old wallets didn't have any defined order for transactions
|
||||||
// Probably a bad idea to change the output of this
|
// Probably a bad idea to change the output of this
|
||||||
|
@ -704,7 +704,7 @@ DBErrors CWallet::ReorderTransactions()
|
||||||
txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr)));
|
txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr)));
|
||||||
}
|
}
|
||||||
std::list<CAccountingEntry> acentries;
|
std::list<CAccountingEntry> acentries;
|
||||||
walletdb.ListAccountCreditDebit("", acentries);
|
batch.ListAccountCreditDebit("", acentries);
|
||||||
for (CAccountingEntry& entry : acentries)
|
for (CAccountingEntry& entry : acentries)
|
||||||
{
|
{
|
||||||
txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry)));
|
txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry)));
|
||||||
|
@ -725,11 +725,11 @@ DBErrors CWallet::ReorderTransactions()
|
||||||
|
|
||||||
if (pwtx)
|
if (pwtx)
|
||||||
{
|
{
|
||||||
if (!walletdb.WriteTx(*pwtx))
|
if (!batch.WriteTx(*pwtx))
|
||||||
return DBErrors::LOAD_FAIL;
|
return DBErrors::LOAD_FAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
|
if (!batch.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
|
||||||
return DBErrors::LOAD_FAIL;
|
return DBErrors::LOAD_FAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -749,60 +749,60 @@ DBErrors CWallet::ReorderTransactions()
|
||||||
// Since we're changing the order, write it back
|
// Since we're changing the order, write it back
|
||||||
if (pwtx)
|
if (pwtx)
|
||||||
{
|
{
|
||||||
if (!walletdb.WriteTx(*pwtx))
|
if (!batch.WriteTx(*pwtx))
|
||||||
return DBErrors::LOAD_FAIL;
|
return DBErrors::LOAD_FAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
|
if (!batch.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
|
||||||
return DBErrors::LOAD_FAIL;
|
return DBErrors::LOAD_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
walletdb.WriteOrderPosNext(nOrderPosNext);
|
batch.WriteOrderPosNext(nOrderPosNext);
|
||||||
|
|
||||||
return DBErrors::LOAD_OK;
|
return DBErrors::LOAD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
int64_t CWallet::IncOrderPosNext(WalletBatch *batch)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // nOrderPosNext
|
AssertLockHeld(cs_wallet); // nOrderPosNext
|
||||||
int64_t nRet = nOrderPosNext++;
|
int64_t nRet = nOrderPosNext++;
|
||||||
if (pwalletdb) {
|
if (batch) {
|
||||||
pwalletdb->WriteOrderPosNext(nOrderPosNext);
|
batch->WriteOrderPosNext(nOrderPosNext);
|
||||||
} else {
|
} else {
|
||||||
CWalletDB(*dbw).WriteOrderPosNext(nOrderPosNext);
|
WalletBatch(*database).WriteOrderPosNext(nOrderPosNext);
|
||||||
}
|
}
|
||||||
return nRet;
|
return nRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment)
|
bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
if (!walletdb.TxnBegin())
|
if (!batch.TxnBegin())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int64_t nNow = GetAdjustedTime();
|
int64_t nNow = GetAdjustedTime();
|
||||||
|
|
||||||
// Debit
|
// Debit
|
||||||
CAccountingEntry debit;
|
CAccountingEntry debit;
|
||||||
debit.nOrderPos = IncOrderPosNext(&walletdb);
|
debit.nOrderPos = IncOrderPosNext(&batch);
|
||||||
debit.strAccount = strFrom;
|
debit.strAccount = strFrom;
|
||||||
debit.nCreditDebit = -nAmount;
|
debit.nCreditDebit = -nAmount;
|
||||||
debit.nTime = nNow;
|
debit.nTime = nNow;
|
||||||
debit.strOtherAccount = strTo;
|
debit.strOtherAccount = strTo;
|
||||||
debit.strComment = strComment;
|
debit.strComment = strComment;
|
||||||
AddAccountingEntry(debit, &walletdb);
|
AddAccountingEntry(debit, &batch);
|
||||||
|
|
||||||
// Credit
|
// Credit
|
||||||
CAccountingEntry credit;
|
CAccountingEntry credit;
|
||||||
credit.nOrderPos = IncOrderPosNext(&walletdb);
|
credit.nOrderPos = IncOrderPosNext(&batch);
|
||||||
credit.strAccount = strTo;
|
credit.strAccount = strTo;
|
||||||
credit.nCreditDebit = nAmount;
|
credit.nCreditDebit = nAmount;
|
||||||
credit.nTime = nNow;
|
credit.nTime = nNow;
|
||||||
credit.strOtherAccount = strFrom;
|
credit.strOtherAccount = strFrom;
|
||||||
credit.strComment = strComment;
|
credit.strComment = strComment;
|
||||||
AddAccountingEntry(credit, &walletdb);
|
AddAccountingEntry(credit, &batch);
|
||||||
|
|
||||||
if (!walletdb.TxnCommit())
|
if (!batch.TxnCommit())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -810,10 +810,10 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
|
||||||
|
|
||||||
bool CWallet::GetLabelDestination(CTxDestination &dest, const std::string& label, bool bForceNew)
|
bool CWallet::GetLabelDestination(CTxDestination &dest, const std::string& label, bool bForceNew)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
CAccount account;
|
CAccount account;
|
||||||
walletdb.ReadAccount(label, account);
|
batch.ReadAccount(label, account);
|
||||||
|
|
||||||
if (!bForceNew) {
|
if (!bForceNew) {
|
||||||
if (!account.vchPubKey.IsValid())
|
if (!account.vchPubKey.IsValid())
|
||||||
|
@ -840,7 +840,7 @@ bool CWallet::GetLabelDestination(CTxDestination &dest, const std::string& label
|
||||||
LearnRelatedScripts(account.vchPubKey, m_default_address_type);
|
LearnRelatedScripts(account.vchPubKey, m_default_address_type);
|
||||||
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
||||||
SetAddressBook(dest, label, "receive");
|
SetAddressBook(dest, label, "receive");
|
||||||
walletdb.WriteAccount(label, account);
|
batch.WriteAccount(label, account);
|
||||||
} else {
|
} else {
|
||||||
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
dest = GetDestinationForKey(account.vchPubKey, m_default_address_type);
|
||||||
}
|
}
|
||||||
|
@ -873,11 +873,11 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
|
||||||
|
|
||||||
wtx.mapValue["replaced_by_txid"] = newHash.ToString();
|
wtx.mapValue["replaced_by_txid"] = newHash.ToString();
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw, "r+");
|
WalletBatch batch(*database, "r+");
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
if (!walletdb.WriteTx(wtx)) {
|
if (!batch.WriteTx(wtx)) {
|
||||||
LogPrintf("%s: Updating walletdb tx %s failed\n", __func__, wtx.GetHash().ToString());
|
LogPrintf("%s: Updating batch tx %s failed\n", __func__, wtx.GetHash().ToString());
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,7 +890,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw, "r+", fFlushOnClose);
|
WalletBatch batch(*database, "r+", fFlushOnClose);
|
||||||
|
|
||||||
uint256 hash = wtxIn.GetHash();
|
uint256 hash = wtxIn.GetHash();
|
||||||
|
|
||||||
|
@ -902,7 +902,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
||||||
if (fInsertedNew)
|
if (fInsertedNew)
|
||||||
{
|
{
|
||||||
wtx.nTimeReceived = GetAdjustedTime();
|
wtx.nTimeReceived = GetAdjustedTime();
|
||||||
wtx.nOrderPos = IncOrderPosNext(&walletdb);
|
wtx.nOrderPos = IncOrderPosNext(&batch);
|
||||||
wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
|
wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
|
||||||
wtx.nTimeSmart = ComputeTimeSmart(wtx);
|
wtx.nTimeSmart = ComputeTimeSmart(wtx);
|
||||||
AddToSpends(hash);
|
AddToSpends(hash);
|
||||||
|
@ -949,7 +949,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
||||||
|
|
||||||
// Write to disk
|
// Write to disk
|
||||||
if (fInsertedNew || fUpdated)
|
if (fInsertedNew || fUpdated)
|
||||||
if (!walletdb.WriteTx(wtx))
|
if (!batch.WriteTx(wtx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Break debit/credit balance caches:
|
// Break debit/credit balance caches:
|
||||||
|
@ -1074,7 +1074,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw, "r+");
|
WalletBatch batch(*database, "r+");
|
||||||
|
|
||||||
std::set<uint256> todo;
|
std::set<uint256> todo;
|
||||||
std::set<uint256> done;
|
std::set<uint256> done;
|
||||||
|
@ -1106,7 +1106,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||||
wtx.nIndex = -1;
|
wtx.nIndex = -1;
|
||||||
wtx.setAbandoned();
|
wtx.setAbandoned();
|
||||||
wtx.MarkDirty();
|
wtx.MarkDirty();
|
||||||
walletdb.WriteTx(wtx);
|
batch.WriteTx(wtx);
|
||||||
NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
|
NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
|
||||||
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
|
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
|
||||||
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0));
|
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0));
|
||||||
|
@ -1148,7 +1148,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Do not flush the wallet here for performance reasons
|
// Do not flush the wallet here for performance reasons
|
||||||
CWalletDB walletdb(*dbw, "r+", false);
|
WalletBatch batch(*database, "r+", false);
|
||||||
|
|
||||||
std::set<uint256> todo;
|
std::set<uint256> todo;
|
||||||
std::set<uint256> done;
|
std::set<uint256> done;
|
||||||
|
@ -1169,7 +1169,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||||
wtx.nIndex = -1;
|
wtx.nIndex = -1;
|
||||||
wtx.hashBlock = hashBlock;
|
wtx.hashBlock = hashBlock;
|
||||||
wtx.MarkDirty();
|
wtx.MarkDirty();
|
||||||
walletdb.WriteTx(wtx);
|
batch.WriteTx(wtx);
|
||||||
// Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
|
// Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
|
||||||
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
|
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
|
||||||
while (iter != mapTxSpends.end() && iter->first.hash == now) {
|
while (iter != mapTxSpends.end() && iter->first.hash == now) {
|
||||||
|
@ -1473,7 +1473,7 @@ bool CWallet::SetHDMasterKey(const CPubKey& pubkey)
|
||||||
bool CWallet::SetHDChain(const CHDChain& chain, bool memonly)
|
bool CWallet::SetHDChain(const CHDChain& chain, bool memonly)
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
if (!memonly && !CWalletDB(*dbw).WriteHDChain(chain))
|
if (!memonly && !WalletBatch(*database).WriteHDChain(chain))
|
||||||
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
|
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
|
||||||
|
|
||||||
hdChain = chain;
|
hdChain = chain;
|
||||||
|
@ -2231,7 +2231,7 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
if (account) {
|
if (account) {
|
||||||
balance += CWalletDB(*dbw).GetAccountCreditDebit(*account);
|
balance += WalletBatch(*database).GetAccountCreditDebit(*account);
|
||||||
}
|
}
|
||||||
|
|
||||||
return balance;
|
return balance;
|
||||||
|
@ -3115,20 +3115,20 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
|
void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
return walletdb.ListAccountCreditDebit(strAccount, entries);
|
return batch.ListAccountCreditDebit(strAccount, entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry)
|
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry)
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
return AddAccountingEntry(acentry, &walletdb);
|
return AddAccountingEntry(acentry, &batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, CWalletDB *pwalletdb)
|
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry, WalletBatch *batch)
|
||||||
{
|
{
|
||||||
if (!pwalletdb->WriteAccountingEntry(++nAccountingEntryNumber, acentry)) {
|
if (!batch->WriteAccountingEntry(++nAccountingEntryNumber, acentry)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3144,10 +3144,10 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
|
||||||
fFirstRunRet = false;
|
fFirstRunRet = false;
|
||||||
DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
|
DBErrors nLoadWalletRet = WalletBatch(*database,"cr+").LoadWallet(this);
|
||||||
if (nLoadWalletRet == DBErrors::NEED_REWRITE)
|
if (nLoadWalletRet == DBErrors::NEED_REWRITE)
|
||||||
{
|
{
|
||||||
if (dbw->Rewrite("\x04pool"))
|
if (database->Rewrite("\x04pool"))
|
||||||
{
|
{
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
@ -3172,13 +3172,13 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||||
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
|
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapWallet
|
AssertLockHeld(cs_wallet); // mapWallet
|
||||||
DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut);
|
DBErrors nZapSelectTxRet = WalletBatch(*database,"cr+").ZapSelectTx(vHashIn, vHashOut);
|
||||||
for (uint256 hash : vHashOut)
|
for (uint256 hash : vHashOut)
|
||||||
mapWallet.erase(hash);
|
mapWallet.erase(hash);
|
||||||
|
|
||||||
if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
|
if (nZapSelectTxRet == DBErrors::NEED_REWRITE)
|
||||||
{
|
{
|
||||||
if (dbw->Rewrite("\x04pool"))
|
if (database->Rewrite("\x04pool"))
|
||||||
{
|
{
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
@ -3200,10 +3200,10 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
|
||||||
|
|
||||||
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
||||||
{
|
{
|
||||||
DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx);
|
DBErrors nZapWalletTxRet = WalletBatch(*database,"cr+").ZapWalletTx(vWtx);
|
||||||
if (nZapWalletTxRet == DBErrors::NEED_REWRITE)
|
if (nZapWalletTxRet == DBErrors::NEED_REWRITE)
|
||||||
{
|
{
|
||||||
if (dbw->Rewrite("\x04pool"))
|
if (database->Rewrite("\x04pool"))
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
|
@ -3235,9 +3235,9 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
|
||||||
}
|
}
|
||||||
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
|
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
|
||||||
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
|
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
|
||||||
if (!strPurpose.empty() && !CWalletDB(*dbw).WritePurpose(EncodeDestination(address), strPurpose))
|
if (!strPurpose.empty() && !WalletBatch(*database).WritePurpose(EncodeDestination(address), strPurpose))
|
||||||
return false;
|
return false;
|
||||||
return CWalletDB(*dbw).WriteName(EncodeDestination(address), strName);
|
return WalletBatch(*database).WriteName(EncodeDestination(address), strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::DelAddressBook(const CTxDestination& address)
|
bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||||
|
@ -3249,15 +3249,15 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||||
std::string strAddress = EncodeDestination(address);
|
std::string strAddress = EncodeDestination(address);
|
||||||
for (const std::pair<std::string, std::string> &item : mapAddressBook[address].destdata)
|
for (const std::pair<std::string, std::string> &item : mapAddressBook[address].destdata)
|
||||||
{
|
{
|
||||||
CWalletDB(*dbw).EraseDestData(strAddress, item.first);
|
WalletBatch(*database).EraseDestData(strAddress, item.first);
|
||||||
}
|
}
|
||||||
mapAddressBook.erase(address);
|
mapAddressBook.erase(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
|
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
|
||||||
|
|
||||||
CWalletDB(*dbw).ErasePurpose(EncodeDestination(address));
|
WalletBatch(*database).ErasePurpose(EncodeDestination(address));
|
||||||
return CWalletDB(*dbw).EraseName(EncodeDestination(address));
|
return WalletBatch(*database).EraseName(EncodeDestination(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& CWallet::GetLabelName(const CScript& scriptPubKey) const
|
const std::string& CWallet::GetLabelName(const CScript& scriptPubKey) const
|
||||||
|
@ -3283,15 +3283,15 @@ bool CWallet::NewKeyPool()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
for (int64_t nIndex : setInternalKeyPool) {
|
for (int64_t nIndex : setInternalKeyPool) {
|
||||||
walletdb.ErasePool(nIndex);
|
batch.ErasePool(nIndex);
|
||||||
}
|
}
|
||||||
setInternalKeyPool.clear();
|
setInternalKeyPool.clear();
|
||||||
|
|
||||||
for (int64_t nIndex : setExternalKeyPool) {
|
for (int64_t nIndex : setExternalKeyPool) {
|
||||||
walletdb.ErasePool(nIndex);
|
batch.ErasePool(nIndex);
|
||||||
}
|
}
|
||||||
setExternalKeyPool.clear();
|
setExternalKeyPool.clear();
|
||||||
|
|
||||||
|
@ -3356,7 +3356,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
||||||
missingInternal = 0;
|
missingInternal = 0;
|
||||||
}
|
}
|
||||||
bool internal = false;
|
bool internal = false;
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
for (int64_t i = missingInternal + missingExternal; i--;)
|
for (int64_t i = missingInternal + missingExternal; i--;)
|
||||||
{
|
{
|
||||||
if (i < missingInternal) {
|
if (i < missingInternal) {
|
||||||
|
@ -3366,8 +3366,8 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
||||||
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
|
||||||
int64_t index = ++m_max_keypool_index;
|
int64_t index = ++m_max_keypool_index;
|
||||||
|
|
||||||
CPubKey pubkey(GenerateNewKey(walletdb, internal));
|
CPubKey pubkey(GenerateNewKey(batch, internal));
|
||||||
if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) {
|
if (!batch.WritePool(index, CKeyPool(pubkey, internal))) {
|
||||||
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
|
throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3402,12 +3402,12 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
|
||||||
if(setKeyPool.empty())
|
if(setKeyPool.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
auto it = setKeyPool.begin();
|
auto it = setKeyPool.begin();
|
||||||
nIndex = *it;
|
nIndex = *it;
|
||||||
setKeyPool.erase(it);
|
setKeyPool.erase(it);
|
||||||
if (!walletdb.ReadPool(nIndex, keypool)) {
|
if (!batch.ReadPool(nIndex, keypool)) {
|
||||||
throw std::runtime_error(std::string(__func__) + ": read failed");
|
throw std::runtime_error(std::string(__func__) + ": read failed");
|
||||||
}
|
}
|
||||||
if (!HaveKey(keypool.vchPubKey.GetID())) {
|
if (!HaveKey(keypool.vchPubKey.GetID())) {
|
||||||
|
@ -3426,8 +3426,8 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRe
|
||||||
void CWallet::KeepKey(int64_t nIndex)
|
void CWallet::KeepKey(int64_t nIndex)
|
||||||
{
|
{
|
||||||
// Remove from key pool
|
// Remove from key pool
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
walletdb.ErasePool(nIndex);
|
batch.ErasePool(nIndex);
|
||||||
LogPrintf("keypool keep %d\n", nIndex);
|
LogPrintf("keypool keep %d\n", nIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3456,8 +3456,8 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
|
||||||
if (nIndex == -1)
|
if (nIndex == -1)
|
||||||
{
|
{
|
||||||
if (IsLocked()) return false;
|
if (IsLocked()) return false;
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
result = GenerateNewKey(walletdb, internal);
|
result = GenerateNewKey(batch, internal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
KeepKey(nIndex);
|
KeepKey(nIndex);
|
||||||
|
@ -3466,14 +3466,14 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, CWalletDB& walletdb) {
|
static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
|
||||||
if (setKeyPool.empty()) {
|
if (setKeyPool.empty()) {
|
||||||
return GetTime();
|
return GetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
int64_t nIndex = *(setKeyPool.begin());
|
int64_t nIndex = *(setKeyPool.begin());
|
||||||
if (!walletdb.ReadPool(nIndex, keypool)) {
|
if (!batch.ReadPool(nIndex, keypool)) {
|
||||||
throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
|
throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
|
||||||
}
|
}
|
||||||
assert(keypool.vchPubKey.IsValid());
|
assert(keypool.vchPubKey.IsValid());
|
||||||
|
@ -3484,12 +3484,12 @@ int64_t CWallet::GetOldestKeyPoolTime()
|
||||||
{
|
{
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
|
|
||||||
// load oldest key from keypool, get time and return
|
// load oldest key from keypool, get time and return
|
||||||
int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, walletdb);
|
int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, batch);
|
||||||
if (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT)) {
|
if (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT)) {
|
||||||
oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, walletdb), oldestKey);
|
oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, batch), oldestKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return oldestKey;
|
return oldestKey;
|
||||||
|
@ -3685,17 +3685,17 @@ void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id)
|
||||||
std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : &setExternalKeyPool;
|
std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : &setExternalKeyPool;
|
||||||
auto it = setKeyPool->begin();
|
auto it = setKeyPool->begin();
|
||||||
|
|
||||||
CWalletDB walletdb(*dbw);
|
WalletBatch batch(*database);
|
||||||
while (it != std::end(*setKeyPool)) {
|
while (it != std::end(*setKeyPool)) {
|
||||||
const int64_t& index = *(it);
|
const int64_t& index = *(it);
|
||||||
if (index > keypool_id) break; // set*KeyPool is ordered
|
if (index > keypool_id) break; // set*KeyPool is ordered
|
||||||
|
|
||||||
CKeyPool keypool;
|
CKeyPool keypool;
|
||||||
if (walletdb.ReadPool(index, keypool)) { //TODO: This should be unnecessary
|
if (batch.ReadPool(index, keypool)) { //TODO: This should be unnecessary
|
||||||
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
|
m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
|
||||||
}
|
}
|
||||||
LearnAllRelatedScripts(keypool.vchPubKey);
|
LearnAllRelatedScripts(keypool.vchPubKey);
|
||||||
walletdb.ErasePool(index);
|
batch.ErasePool(index);
|
||||||
LogPrintf("keypool index %d removed\n", index);
|
LogPrintf("keypool index %d removed\n", index);
|
||||||
it = setKeyPool->erase(it);
|
it = setKeyPool->erase(it);
|
||||||
}
|
}
|
||||||
|
@ -3872,14 +3872,14 @@ bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, co
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
|
mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
|
||||||
return CWalletDB(*dbw).WriteDestData(EncodeDestination(dest), key, value);
|
return WalletBatch(*database).WriteDestData(EncodeDestination(dest), key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
||||||
{
|
{
|
||||||
if (!mapAddressBook[dest].destdata.erase(key))
|
if (!mapAddressBook[dest].destdata.erase(key))
|
||||||
return false;
|
return false;
|
||||||
return CWalletDB(*dbw).EraseDestData(EncodeDestination(dest), key);
|
return WalletBatch(*database).EraseDestData(EncodeDestination(dest), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
|
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
|
||||||
|
@ -3928,7 +3928,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
|
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
|
||||||
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
||||||
|
|
||||||
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(name, CWalletDBWrapper::Create(path));
|
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(name, WalletDatabase::Create(path));
|
||||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||||
if (nZapWalletRet != DBErrors::LOAD_OK) {
|
if (nZapWalletRet != DBErrors::LOAD_OK) {
|
||||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||||
|
@ -3940,7 +3940,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
|
|
||||||
int64_t nStart = GetTimeMillis();
|
int64_t nStart = GetTimeMillis();
|
||||||
bool fFirstRun = true;
|
bool fFirstRun = true;
|
||||||
CWallet *walletInstance = new CWallet(name, CWalletDBWrapper::Create(path));
|
CWallet *walletInstance = new CWallet(name, WalletDatabase::Create(path));
|
||||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
||||||
if (nLoadWalletRet != DBErrors::LOAD_OK)
|
if (nLoadWalletRet != DBErrors::LOAD_OK)
|
||||||
{
|
{
|
||||||
|
@ -4045,9 +4045,9 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
CBlockIndex *pindexRescan = chainActive.Genesis();
|
CBlockIndex *pindexRescan = chainActive.Genesis();
|
||||||
if (!gArgs.GetBoolArg("-rescan", false))
|
if (!gArgs.GetBoolArg("-rescan", false))
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*walletInstance->dbw);
|
WalletBatch batch(*walletInstance->database);
|
||||||
CBlockLocator locator;
|
CBlockLocator locator;
|
||||||
if (walletdb.ReadBestBlock(locator))
|
if (batch.ReadBestBlock(locator))
|
||||||
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
|
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4091,12 +4091,12 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
}
|
}
|
||||||
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
|
LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
|
||||||
walletInstance->SetBestChain(chainActive.GetLocator());
|
walletInstance->SetBestChain(chainActive.GetLocator());
|
||||||
walletInstance->dbw->IncrementUpdateCounter();
|
walletInstance->database->IncrementUpdateCounter();
|
||||||
|
|
||||||
// Restore wallet transaction metadata after -zapwallettxes=1
|
// Restore wallet transaction metadata after -zapwallettxes=1
|
||||||
if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2")
|
if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2")
|
||||||
{
|
{
|
||||||
CWalletDB walletdb(*walletInstance->dbw);
|
WalletBatch batch(*walletInstance->database);
|
||||||
|
|
||||||
for (const CWalletTx& wtxOld : vWtx)
|
for (const CWalletTx& wtxOld : vWtx)
|
||||||
{
|
{
|
||||||
|
@ -4113,7 +4113,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
|
||||||
copyTo->fFromMe = copyFrom->fFromMe;
|
copyTo->fFromMe = copyFrom->fFromMe;
|
||||||
copyTo->strFromAccount = copyFrom->strFromAccount;
|
copyTo->strFromAccount = copyFrom->strFromAccount;
|
||||||
copyTo->nOrderPos = copyFrom->nOrderPos;
|
copyTo->nOrderPos = copyFrom->nOrderPos;
|
||||||
walletdb.WriteTx(*copyTo);
|
batch.WriteTx(*copyTo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4146,7 +4146,7 @@ void CWallet::postInitProcess(CScheduler& scheduler)
|
||||||
|
|
||||||
bool CWallet::BackupWallet(const std::string& strDest)
|
bool CWallet::BackupWallet(const std::string& strDest)
|
||||||
{
|
{
|
||||||
return dbw->Backup(strDest);
|
return database->Backup(strDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
CKeyPool::CKeyPool()
|
CKeyPool::CKeyPool()
|
||||||
|
|
|
@ -666,7 +666,7 @@ private:
|
||||||
std::mutex mutexScanning;
|
std::mutex mutexScanning;
|
||||||
friend class WalletRescanReserver;
|
friend class WalletRescanReserver;
|
||||||
|
|
||||||
CWalletDB *pwalletdbEncryption = nullptr;
|
WalletBatch *encrypted_batch = nullptr;
|
||||||
|
|
||||||
//! the current wallet version: clients below this version are not able to load the wallet
|
//! the current wallet version: clients below this version are not able to load the wallet
|
||||||
int nWalletVersion = FEATURE_BASE;
|
int nWalletVersion = FEATURE_BASE;
|
||||||
|
@ -701,7 +701,7 @@ private:
|
||||||
CHDChain hdChain;
|
CHDChain hdChain;
|
||||||
|
|
||||||
/* HD derive new child key (on internal or external chain) */
|
/* HD derive new child key (on internal or external chain) */
|
||||||
void DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKey& secret, bool internal = false);
|
void DeriveNewChildKey(WalletBatch &batch, CKeyMetadata& metadata, CKey& secret, bool internal = false);
|
||||||
|
|
||||||
std::set<int64_t> setInternalKeyPool;
|
std::set<int64_t> setInternalKeyPool;
|
||||||
std::set<int64_t> setExternalKeyPool;
|
std::set<int64_t> setExternalKeyPool;
|
||||||
|
@ -729,7 +729,7 @@ private:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
/** Internal database handle. */
|
/** Internal database handle. */
|
||||||
std::unique_ptr<CWalletDBWrapper> dbw;
|
std::unique_ptr<WalletDatabase> database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The following is used to keep track of how far behind the wallet is
|
* The following is used to keep track of how far behind the wallet is
|
||||||
|
@ -753,9 +753,9 @@ public:
|
||||||
/** Get database handle used by this wallet. Ideally this function would
|
/** Get database handle used by this wallet. Ideally this function would
|
||||||
* not be necessary.
|
* not be necessary.
|
||||||
*/
|
*/
|
||||||
CWalletDBWrapper& GetDBHandle()
|
WalletDatabase& GetDBHandle()
|
||||||
{
|
{
|
||||||
return *dbw;
|
return *database;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -783,14 +783,14 @@ public:
|
||||||
unsigned int nMasterKeyMaxID = 0;
|
unsigned int nMasterKeyMaxID = 0;
|
||||||
|
|
||||||
/** Construct wallet with specified name and database implementation. */
|
/** Construct wallet with specified name and database implementation. */
|
||||||
CWallet(std::string name, std::unique_ptr<CWalletDBWrapper> dbw) : m_name(std::move(name)), dbw(std::move(dbw))
|
CWallet(std::string name, std::unique_ptr<WalletDatabase> database) : m_name(std::move(name)), database(std::move(database))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~CWallet()
|
~CWallet()
|
||||||
{
|
{
|
||||||
delete pwalletdbEncryption;
|
delete encrypted_batch;
|
||||||
pwalletdbEncryption = nullptr;
|
encrypted_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<uint256, CWalletTx> mapWallet;
|
std::map<uint256, CWalletTx> mapWallet;
|
||||||
|
@ -856,10 +856,10 @@ public:
|
||||||
* keystore implementation
|
* keystore implementation
|
||||||
* Generate a new key
|
* Generate a new key
|
||||||
*/
|
*/
|
||||||
CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false);
|
CPubKey GenerateNewKey(WalletBatch& batch, bool internal = false);
|
||||||
//! Adds a key to the store, and saves it to disk.
|
//! Adds a key to the store, and saves it to disk.
|
||||||
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
|
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
|
||||||
bool AddKeyPubKeyWithDB(CWalletDB &walletdb,const CKey& key, const CPubKey &pubkey);
|
bool AddKeyPubKeyWithDB(WalletBatch &batch,const CKey& key, const CPubKey &pubkey);
|
||||||
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
|
//! Adds a key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
|
bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); }
|
||||||
//! Load metadata (used by LoadWallet)
|
//! Load metadata (used by LoadWallet)
|
||||||
|
@ -907,7 +907,7 @@ public:
|
||||||
* Increment the next transaction order id
|
* Increment the next transaction order id
|
||||||
* @return next transaction order id
|
* @return next transaction order id
|
||||||
*/
|
*/
|
||||||
int64_t IncOrderPosNext(CWalletDB *pwalletdb = nullptr);
|
int64_t IncOrderPosNext(WalletBatch *batch = nullptr);
|
||||||
DBErrors ReorderTransactions();
|
DBErrors ReorderTransactions();
|
||||||
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
|
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = "");
|
||||||
bool GetLabelDestination(CTxDestination &dest, const std::string& label, bool bForceNew = false);
|
bool GetLabelDestination(CTxDestination &dest, const std::string& label, bool bForceNew = false);
|
||||||
|
@ -955,7 +955,7 @@ public:
|
||||||
|
|
||||||
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries);
|
||||||
bool AddAccountingEntry(const CAccountingEntry&);
|
bool AddAccountingEntry(const CAccountingEntry&);
|
||||||
bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb);
|
bool AddAccountingEntry(const CAccountingEntry&, WalletBatch *batch);
|
||||||
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts) const
|
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts) const
|
||||||
{
|
{
|
||||||
std::vector<CTxOut> v_txouts(txouts.size());
|
std::vector<CTxOut> v_txouts(txouts.size());
|
||||||
|
@ -1039,7 +1039,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
|
//! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
|
||||||
bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = nullptr, bool fExplicit = false);
|
bool SetMinVersion(enum WalletFeature, WalletBatch* batch_in = nullptr, bool fExplicit = false);
|
||||||
|
|
||||||
//! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
|
//! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
|
||||||
bool SetMaxVersion(int nVersion);
|
bool SetMaxVersion(int nVersion);
|
||||||
|
|
|
@ -21,42 +21,42 @@
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
//
|
//
|
||||||
// CWalletDB
|
// WalletBatch
|
||||||
//
|
//
|
||||||
|
|
||||||
bool CWalletDB::WriteName(const std::string& strAddress, const std::string& strName)
|
bool WalletBatch::WriteName(const std::string& strAddress, const std::string& strName)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("name"), strAddress), strName);
|
return WriteIC(std::make_pair(std::string("name"), strAddress), strName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::EraseName(const std::string& strAddress)
|
bool WalletBatch::EraseName(const std::string& strAddress)
|
||||||
{
|
{
|
||||||
// This should only be used for sending addresses, never for receiving addresses,
|
// This should only be used for sending addresses, never for receiving addresses,
|
||||||
// receiving addresses must always have an address book entry if they're not change return.
|
// receiving addresses must always have an address book entry if they're not change return.
|
||||||
return EraseIC(std::make_pair(std::string("name"), strAddress));
|
return EraseIC(std::make_pair(std::string("name"), strAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WritePurpose(const std::string& strAddress, const std::string& strPurpose)
|
bool WalletBatch::WritePurpose(const std::string& strAddress, const std::string& strPurpose)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("purpose"), strAddress), strPurpose);
|
return WriteIC(std::make_pair(std::string("purpose"), strAddress), strPurpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ErasePurpose(const std::string& strAddress)
|
bool WalletBatch::ErasePurpose(const std::string& strAddress)
|
||||||
{
|
{
|
||||||
return EraseIC(std::make_pair(std::string("purpose"), strAddress));
|
return EraseIC(std::make_pair(std::string("purpose"), strAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteTx(const CWalletTx& wtx)
|
bool WalletBatch::WriteTx(const CWalletTx& wtx)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("tx"), wtx.GetHash()), wtx);
|
return WriteIC(std::make_pair(std::string("tx"), wtx.GetHash()), wtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::EraseTx(uint256 hash)
|
bool WalletBatch::EraseTx(uint256 hash)
|
||||||
{
|
{
|
||||||
return EraseIC(std::make_pair(std::string("tx"), hash));
|
return EraseIC(std::make_pair(std::string("tx"), hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
|
bool WalletBatch::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
|
||||||
{
|
{
|
||||||
if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) {
|
if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -71,7 +71,7 @@ bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, c
|
||||||
return WriteIC(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
|
return WriteIC(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
|
bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
const CKeyMetadata &keyMeta)
|
const CKeyMetadata &keyMeta)
|
||||||
{
|
{
|
||||||
|
@ -87,17 +87,17 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
|
bool WalletBatch::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
|
return WriteIC(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
|
bool WalletBatch::WriteCScript(const uint160& hash, const CScript& redeemScript)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("cscript"), hash), redeemScript, false);
|
return WriteIC(std::make_pair(std::string("cscript"), hash), redeemScript, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
|
bool WalletBatch::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
|
||||||
{
|
{
|
||||||
if (!WriteIC(std::make_pair(std::string("watchmeta"), dest), keyMeta)) {
|
if (!WriteIC(std::make_pair(std::string("watchmeta"), dest), keyMeta)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -105,7 +105,7 @@ bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
|
||||||
return WriteIC(std::make_pair(std::string("watchs"), dest), '1');
|
return WriteIC(std::make_pair(std::string("watchs"), dest), '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::EraseWatchOnly(const CScript &dest)
|
bool WalletBatch::EraseWatchOnly(const CScript &dest)
|
||||||
{
|
{
|
||||||
if (!EraseIC(std::make_pair(std::string("watchmeta"), dest))) {
|
if (!EraseIC(std::make_pair(std::string("watchmeta"), dest))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -113,60 +113,60 @@ bool CWalletDB::EraseWatchOnly(const CScript &dest)
|
||||||
return EraseIC(std::make_pair(std::string("watchs"), dest));
|
return EraseIC(std::make_pair(std::string("watchs"), dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
|
bool WalletBatch::WriteBestBlock(const CBlockLocator& locator)
|
||||||
{
|
{
|
||||||
WriteIC(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
|
WriteIC(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
|
||||||
return WriteIC(std::string("bestblock_nomerkle"), locator);
|
return WriteIC(std::string("bestblock_nomerkle"), locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
|
bool WalletBatch::ReadBestBlock(CBlockLocator& locator)
|
||||||
{
|
{
|
||||||
if (batch.Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
|
if (batch.Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
|
||||||
return batch.Read(std::string("bestblock_nomerkle"), locator);
|
return batch.Read(std::string("bestblock_nomerkle"), locator);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext)
|
bool WalletBatch::WriteOrderPosNext(int64_t nOrderPosNext)
|
||||||
{
|
{
|
||||||
return WriteIC(std::string("orderposnext"), nOrderPosNext);
|
return WriteIC(std::string("orderposnext"), nOrderPosNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool)
|
bool WalletBatch::ReadPool(int64_t nPool, CKeyPool& keypool)
|
||||||
{
|
{
|
||||||
return batch.Read(std::make_pair(std::string("pool"), nPool), keypool);
|
return batch.Read(std::make_pair(std::string("pool"), nPool), keypool);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool)
|
bool WalletBatch::WritePool(int64_t nPool, const CKeyPool& keypool)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("pool"), nPool), keypool);
|
return WriteIC(std::make_pair(std::string("pool"), nPool), keypool);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ErasePool(int64_t nPool)
|
bool WalletBatch::ErasePool(int64_t nPool)
|
||||||
{
|
{
|
||||||
return EraseIC(std::make_pair(std::string("pool"), nPool));
|
return EraseIC(std::make_pair(std::string("pool"), nPool));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteMinVersion(int nVersion)
|
bool WalletBatch::WriteMinVersion(int nVersion)
|
||||||
{
|
{
|
||||||
return WriteIC(std::string("minversion"), nVersion);
|
return WriteIC(std::string("minversion"), nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ReadAccount(const std::string& strAccount, CAccount& account)
|
bool WalletBatch::ReadAccount(const std::string& strAccount, CAccount& account)
|
||||||
{
|
{
|
||||||
account.SetNull();
|
account.SetNull();
|
||||||
return batch.Read(std::make_pair(std::string("acc"), strAccount), account);
|
return batch.Read(std::make_pair(std::string("acc"), strAccount), account);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteAccount(const std::string& strAccount, const CAccount& account)
|
bool WalletBatch::WriteAccount(const std::string& strAccount, const CAccount& account)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("acc"), strAccount), account);
|
return WriteIC(std::make_pair(std::string("acc"), strAccount), account);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry)
|
bool WalletBatch::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
|
return WriteIC(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount CWalletDB::GetAccountCreditDebit(const std::string& strAccount)
|
CAmount WalletBatch::GetAccountCreditDebit(const std::string& strAccount)
|
||||||
{
|
{
|
||||||
std::list<CAccountingEntry> entries;
|
std::list<CAccountingEntry> entries;
|
||||||
ListAccountCreditDebit(strAccount, entries);
|
ListAccountCreditDebit(strAccount, entries);
|
||||||
|
@ -178,7 +178,7 @@ CAmount CWalletDB::GetAccountCreditDebit(const std::string& strAccount)
|
||||||
return nCreditDebit;
|
return nCreditDebit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries)
|
void WalletBatch::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries)
|
||||||
{
|
{
|
||||||
bool fAllAccounts = (strAccount == "*");
|
bool fAllAccounts = (strAccount == "*");
|
||||||
|
|
||||||
|
@ -512,13 +512,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::IsKeyType(const std::string& strType)
|
bool WalletBatch::IsKeyType(const std::string& strType)
|
||||||
{
|
{
|
||||||
return (strType== "key" || strType == "wkey" ||
|
return (strType== "key" || strType == "wkey" ||
|
||||||
strType == "mkey" || strType == "ckey");
|
strType == "mkey" || strType == "ckey");
|
||||||
}
|
}
|
||||||
|
|
||||||
DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
|
DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
||||||
{
|
{
|
||||||
CWalletScanState wss;
|
CWalletScanState wss;
|
||||||
bool fNoncriticalErrors = false;
|
bool fNoncriticalErrors = false;
|
||||||
|
@ -624,7 +624,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx)
|
DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx)
|
||||||
{
|
{
|
||||||
DBErrors result = DBErrors::LOAD_OK;
|
DBErrors result = DBErrors::LOAD_OK;
|
||||||
|
|
||||||
|
@ -683,7 +683,7 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBErrors CWalletDB::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uint256>& vTxHashOut)
|
DBErrors WalletBatch::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uint256>& vTxHashOut)
|
||||||
{
|
{
|
||||||
// build list of wallet TXs and hashes
|
// build list of wallet TXs and hashes
|
||||||
std::vector<uint256> vTxHash;
|
std::vector<uint256> vTxHash;
|
||||||
|
@ -721,7 +721,7 @@ DBErrors CWalletDB::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uin
|
||||||
return DBErrors::LOAD_OK;
|
return DBErrors::LOAD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBErrors CWalletDB::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
DBErrors WalletBatch::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
||||||
{
|
{
|
||||||
// build list of wallet TXs
|
// build list of wallet TXs
|
||||||
std::vector<uint256> vTxHash;
|
std::vector<uint256> vTxHash;
|
||||||
|
@ -749,7 +749,7 @@ void MaybeCompactWalletDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWalletRef pwallet : vpwallets) {
|
||||||
CWalletDBWrapper& dbh = pwallet->GetDBHandle();
|
WalletDatabase& dbh = pwallet->GetDBHandle();
|
||||||
|
|
||||||
unsigned int nUpdateCounter = dbh.nUpdateCounter;
|
unsigned int nUpdateCounter = dbh.nUpdateCounter;
|
||||||
|
|
||||||
|
@ -759,7 +759,7 @@ void MaybeCompactWalletDB()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) {
|
if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) {
|
||||||
if (CDB::PeriodicFlush(dbh)) {
|
if (BerkeleyBatch::PeriodicFlush(dbh)) {
|
||||||
dbh.nLastFlushed = nUpdateCounter;
|
dbh.nLastFlushed = nUpdateCounter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,19 +771,19 @@ void MaybeCompactWalletDB()
|
||||||
//
|
//
|
||||||
// Try to (very carefully!) recover wallet file if there is a problem.
|
// Try to (very carefully!) recover wallet file if there is a problem.
|
||||||
//
|
//
|
||||||
bool CWalletDB::Recover(const fs::path& wallet_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename)
|
bool WalletBatch::Recover(const fs::path& wallet_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename)
|
||||||
{
|
{
|
||||||
return CDB::Recover(wallet_path, callbackDataIn, recoverKVcallback, out_backup_filename);
|
return BerkeleyBatch::Recover(wallet_path, callbackDataIn, recoverKVcallback, out_backup_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::Recover(const fs::path& wallet_path, std::string& out_backup_filename)
|
bool WalletBatch::Recover(const fs::path& wallet_path, std::string& out_backup_filename)
|
||||||
{
|
{
|
||||||
// recover without a key filter callback
|
// recover without a key filter callback
|
||||||
// results in recovering all record types
|
// results in recovering all record types
|
||||||
return CWalletDB::Recover(wallet_path, nullptr, nullptr, out_backup_filename);
|
return WalletBatch::Recover(wallet_path, nullptr, nullptr, out_backup_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
|
bool WalletBatch::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
|
||||||
{
|
{
|
||||||
CWallet *dummyWallet = reinterpret_cast<CWallet*>(callbackData);
|
CWallet *dummyWallet = reinterpret_cast<CWallet*>(callbackData);
|
||||||
CWalletScanState dummyWss;
|
CWalletScanState dummyWss;
|
||||||
|
@ -799,60 +799,60 @@ bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDa
|
||||||
return false;
|
return false;
|
||||||
if (!fReadOK)
|
if (!fReadOK)
|
||||||
{
|
{
|
||||||
LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr);
|
LogPrintf("WARNING: WalletBatch::Recover skipping %s: %s\n", strType, strErr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr)
|
bool WalletBatch::VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr)
|
||||||
{
|
{
|
||||||
return CDB::VerifyEnvironment(wallet_path, errorStr);
|
return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr)
|
bool WalletBatch::VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr)
|
||||||
{
|
{
|
||||||
return CDB::VerifyDatabaseFile(wallet_path, warningStr, errorStr, CWalletDB::Recover);
|
return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warningStr, errorStr, WalletBatch::Recover);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
|
bool WalletBatch::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
|
||||||
{
|
{
|
||||||
return WriteIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
|
return WriteIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::EraseDestData(const std::string &address, const std::string &key)
|
bool WalletBatch::EraseDestData(const std::string &address, const std::string &key)
|
||||||
{
|
{
|
||||||
return EraseIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
|
return EraseIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CWalletDB::WriteHDChain(const CHDChain& chain)
|
bool WalletBatch::WriteHDChain(const CHDChain& chain)
|
||||||
{
|
{
|
||||||
return WriteIC(std::string("hdchain"), chain);
|
return WriteIC(std::string("hdchain"), chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::TxnBegin()
|
bool WalletBatch::TxnBegin()
|
||||||
{
|
{
|
||||||
return batch.TxnBegin();
|
return batch.TxnBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::TxnCommit()
|
bool WalletBatch::TxnCommit()
|
||||||
{
|
{
|
||||||
return batch.TxnCommit();
|
return batch.TxnCommit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::TxnAbort()
|
bool WalletBatch::TxnAbort()
|
||||||
{
|
{
|
||||||
return batch.TxnAbort();
|
return batch.TxnAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::ReadVersion(int& nVersion)
|
bool WalletBatch::ReadVersion(int& nVersion)
|
||||||
{
|
{
|
||||||
return batch.ReadVersion(nVersion);
|
return batch.ReadVersion(nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteVersion(int nVersion)
|
bool WalletBatch::WriteVersion(int nVersion)
|
||||||
{
|
{
|
||||||
return batch.WriteVersion(nVersion);
|
return batch.WriteVersion(nVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,15 @@
|
||||||
/**
|
/**
|
||||||
* Overview of wallet database classes:
|
* Overview of wallet database classes:
|
||||||
*
|
*
|
||||||
* - CDBEnv is an environment in which the database exists (has no analog in dbwrapper.h)
|
* - BerkeleyEnvironment is an environment in which the database exists (has no analog in dbwrapper.h)
|
||||||
* - CWalletDBWrapper represents a wallet database (similar to CDBWrapper in dbwrapper.h)
|
* - WalletDatabase represents a wallet database (similar to CDBWrapper in dbwrapper.h)
|
||||||
* - CDB is a low-level database transaction (similar to CDBBatch in dbwrapper.h)
|
* - BerkeleyBatch is a low-level database transaction (similar to CDBBatch in dbwrapper.h)
|
||||||
* - CWalletDB is a modifier object for the wallet, and encapsulates a database
|
* - WalletBatch is a modifier object for the wallet, and encapsulates a database
|
||||||
* transaction as well as methods to act on the database (no analog in
|
* transaction as well as methods to act on the database (no analog in
|
||||||
* dbwrapper.h)
|
* dbwrapper.h)
|
||||||
*
|
*
|
||||||
* The latter two are named confusingly, in contrast to what the names CDB
|
* The latter two are named confusingly, in contrast to what the names BerkeleyBatch
|
||||||
* and CWalletDB suggest they are transient transaction objects and don't
|
* and WalletBatch suggest they are transient transaction objects and don't
|
||||||
* represent the database itself.
|
* represent the database itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -45,6 +45,9 @@ class CWalletTx;
|
||||||
class uint160;
|
class uint160;
|
||||||
class uint256;
|
class uint256;
|
||||||
|
|
||||||
|
/** Backend-agnostic database type. */
|
||||||
|
using WalletDatabase = BerkeleyDatabase;
|
||||||
|
|
||||||
/** Error statuses for the wallet database */
|
/** Error statuses for the wallet database */
|
||||||
enum class DBErrors
|
enum class DBErrors
|
||||||
{
|
{
|
||||||
|
@ -138,7 +141,7 @@ public:
|
||||||
* database. It will be committed when the object goes out of scope.
|
* database. It will be committed when the object goes out of scope.
|
||||||
* Optionally (on by default) it will flush to disk as well.
|
* Optionally (on by default) it will flush to disk as well.
|
||||||
*/
|
*/
|
||||||
class CWalletDB
|
class WalletBatch
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
template <typename K, typename T>
|
template <typename K, typename T>
|
||||||
|
@ -147,7 +150,7 @@ private:
|
||||||
if (!batch.Write(key, value, fOverwrite)) {
|
if (!batch.Write(key, value, fOverwrite)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_dbw.IncrementUpdateCounter();
|
m_database.IncrementUpdateCounter();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,18 +160,18 @@ private:
|
||||||
if (!batch.Erase(key)) {
|
if (!batch.Erase(key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_dbw.IncrementUpdateCounter();
|
m_database.IncrementUpdateCounter();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) :
|
explicit WalletBatch(WalletDatabase& database, const char* pszMode = "r+", bool _fFlushOnClose = true) :
|
||||||
batch(dbw, pszMode, _fFlushOnClose),
|
batch(database, pszMode, _fFlushOnClose),
|
||||||
m_dbw(dbw)
|
m_database(database)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
CWalletDB(const CWalletDB&) = delete;
|
WalletBatch(const WalletBatch&) = delete;
|
||||||
CWalletDB& operator=(const CWalletDB&) = delete;
|
WalletBatch& operator=(const WalletBatch&) = delete;
|
||||||
|
|
||||||
bool WriteName(const std::string& strAddress, const std::string& strName);
|
bool WriteName(const std::string& strAddress, const std::string& strName);
|
||||||
bool EraseName(const std::string& strAddress);
|
bool EraseName(const std::string& strAddress);
|
||||||
|
@ -244,8 +247,8 @@ public:
|
||||||
//! Write wallet version
|
//! Write wallet version
|
||||||
bool WriteVersion(int nVersion);
|
bool WriteVersion(int nVersion);
|
||||||
private:
|
private:
|
||||||
CDB batch;
|
BerkeleyBatch batch;
|
||||||
CWalletDBWrapper& m_dbw;
|
WalletDatabase& m_database;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
|
//! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
|
||||||
|
|
|
@ -77,7 +77,7 @@ class MultiWalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# should not initialize if one wallet is a copy of another
|
# should not initialize if one wallet is a copy of another
|
||||||
shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy'))
|
shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy'))
|
||||||
exp_stderr = "CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)"
|
exp_stderr = "BerkeleyBatch: Can't open database w8_copy \(duplicates fileid \w+ from w8\)"
|
||||||
self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)
|
self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)
|
||||||
|
|
||||||
# should not initialize if wallet file is a symlink
|
# should not initialize if wallet file is a symlink
|
||||||
|
|
Loading…
Reference in a new issue