@ -21,59 +21,47 @@
# include <boost/foreach.hpp>
# include <boost/foreach.hpp>
# include <boost/thread.hpp>
# include <boost/thread.hpp>
static uint64_t nAccountingEntryNumber = 0 ;
static std : : atomic < unsigned int > nWalletDBUpdateCounter ;
//
//
// CWalletDB
// CWalletDB
//
//
bool CWalletDB : : WriteName ( const std : : string & strAddress , const std : : string & strName )
bool CWalletDB : : WriteName ( const std : : string & strAddress , const std : : string & strName )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " name " ) , strAddress ) , strName ) ;
return batch . Write ( std : : make_pair ( std : : string ( " name " ) , strAddress ) , strName ) ;
}
}
bool CWalletDB : : EraseName ( const std : : string & strAddress )
bool CWalletDB : : 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.
nWalletDBUpdateCounter + + ;
return EraseIC ( std : : make_pair ( std : : string ( " name " ) , strAddress ) ) ;
return batch . Erase ( std : : make_pair ( std : : string ( " name " ) , strAddress ) ) ;
}
}
bool CWalletDB : : WritePurpose ( const std : : string & strAddress , const std : : string & strPurpose )
bool CWalletDB : : WritePurpose ( const std : : string & strAddress , const std : : string & strPurpose )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " purpose " ) , strAddress ) , strPurpose ) ;
return batch . Write ( std : : make_pair ( std : : string ( " purpose " ) , strAddress ) , strPurpose ) ;
}
}
bool CWalletDB : : ErasePurpose ( const std : : string & strPurpose )
bool CWalletDB : : ErasePurpose ( const std : : string & strPurpose )
{
{
nWalletDBUpdateCounter + + ;
return EraseIC ( std : : make_pair ( std : : string ( " purpose " ) , strPurpose ) ) ;
return batch . Erase ( std : : make_pair ( std : : string ( " purpose " ) , strPurpose ) ) ;
}
}
bool CWalletDB : : WriteTx ( const CWalletTx & wtx )
bool CWalletDB : : WriteTx ( const CWalletTx & wtx )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " tx " ) , wtx . GetHash ( ) ) , wtx ) ;
return batch . Write ( std : : make_pair ( std : : string ( " tx " ) , wtx . GetHash ( ) ) , wtx ) ;
}
}
bool CWalletDB : : EraseTx ( uint256 hash )
bool CWalletDB : : EraseTx ( uint256 hash )
{
{
nWalletDBUpdateCounter + + ;
return EraseIC ( std : : make_pair ( std : : string ( " tx " ) , hash ) ) ;
return batch . Erase ( std : : make_pair ( std : : string ( " tx " ) , hash ) ) ;
}
}
bool CWalletDB : : WriteKey ( const CPubKey & vchPubKey , const CPrivKey & vchPrivKey , const CKeyMetadata & keyMeta )
bool CWalletDB : : WriteKey ( const CPubKey & vchPubKey , const CPrivKey & vchPrivKey , const CKeyMetadata & keyMeta )
{
{
nWalletDBUpdateCounter + + ;
if ( ! WriteIC ( std : : make_pair ( std : : string ( " keymeta " ) , vchPubKey ) , keyMeta , false ) ) {
if ( ! batch . Write ( std : : make_pair ( std : : string ( " keymeta " ) , vchPubKey ) ,
keyMeta , false ) )
return false ;
return false ;
}
// hash pubkey/privkey to accelerate wallet load
// hash pubkey/privkey to accelerate wallet load
std : : vector < unsigned char > vchKey ;
std : : vector < unsigned char > vchKey ;
@ -81,7 +69,7 @@ bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, c
vchKey . insert ( vchKey . end ( ) , vchPubKey . begin ( ) , vchPubKey . end ( ) ) ;
vchKey . insert ( vchKey . end ( ) , vchPubKey . begin ( ) , vchPubKey . end ( ) ) ;
vchKey . insert ( vchKey . end ( ) , vchPrivKey . begin ( ) , vchPrivKey . end ( ) ) ;
vchKey . insert ( vchKey . end ( ) , vchPrivKey . begin ( ) , vchPrivKey . end ( ) ) ;
return batch . Write ( 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 CWalletDB : : WriteCryptedKey ( const CPubKey & vchPubKey ,
@ -89,55 +77,53 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
const CKeyMetadata & keyMeta )
const CKeyMetadata & keyMeta )
{
{
const bool fEraseUnencryptedKey = true ;
const bool fEraseUnencryptedKey = true ;
nWalletDBUpdateCounter + + ;
if ( ! batch . Write ( std : : make_pair ( std : : string ( " keymeta " ) , vchPubKey ) ,
if ( ! WriteIC ( std : : make_pair ( std : : string ( " keymeta " ) , vchPubKey ) , keyMeta ) ) {
keyMeta ) )
return false ;
return false ;
}
if ( ! batch . Write ( std : : make_pair ( std : : string ( " ckey " ) , vchPubKey ) , vchCryptedSecret , false ) )
if ( ! WriteIC ( std : : make_pair ( std : : string ( " ckey " ) , vchPubKey ) , vchCryptedSecret , false ) ) {
return false ;
return false ;
}
if ( fEraseUnencryptedKey )
if ( fEraseUnencryptedKey )
{
{
batch . Erase ( std : : make_pair ( std : : string ( " key " ) , vchPubKey ) ) ;
EraseIC ( std : : make_pair ( std : : string ( " key " ) , vchPubKey ) ) ;
batch . Erase ( std : : make_pair ( std : : string ( " wkey " ) , vchPubKey ) ) ;
EraseIC ( std : : make_pair ( std : : string ( " wkey " ) , vchPubKey ) ) ;
}
}
return true ;
return true ;
}
}
bool CWalletDB : : WriteMasterKey ( unsigned int nID , const CMasterKey & kMasterKey )
bool CWalletDB : : WriteMasterKey ( unsigned int nID , const CMasterKey & kMasterKey )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " mkey " ) , nID ) , kMasterKey , true ) ;
return batch . Write ( std : : make_pair ( std : : string ( " mkey " ) , nID ) , kMasterKey , true ) ;
}
}
bool CWalletDB : : WriteCScript ( const uint160 & hash , const CScript & redeemScript )
bool CWalletDB : : WriteCScript ( const uint160 & hash , const CScript & redeemScript )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " cscript " ) , hash ) , * ( const CScriptBase * ) ( & redeemScript ) , false ) ;
return batch . Write ( std : : make_pair ( std : : string ( " cscript " ) , hash ) , * ( const CScriptBase * ) ( & redeemScript ) , false ) ;
}
}
bool CWalletDB : : WriteWatchOnly ( const CScript & dest , const CKeyMetadata & keyMeta )
bool CWalletDB : : WriteWatchOnly ( const CScript & dest , const CKeyMetadata & keyMeta )
{
{
nWalletDBUpdateCounter + + ;
if ( ! WriteIC ( std : : make_pair ( std : : string ( " watchmeta " ) , * ( const CScriptBase * ) ( & dest ) ) , keyMeta ) ) {
if ( ! batch . Write ( std : : make_pair ( std : : string ( " watchmeta " ) , * ( const CScriptBase * ) ( & dest ) ) , keyMeta ) )
return false ;
return false ;
return batch . Write ( std : : make_pair ( std : : string ( " watchs " ) , * ( const CScriptBase * ) ( & dest ) ) , ' 1 ' ) ;
}
return WriteIC ( std : : make_pair ( std : : string ( " watchs " ) , * ( const CScriptBase * ) ( & dest ) ) , ' 1 ' ) ;
}
}
bool CWalletDB : : EraseWatchOnly ( const CScript & dest )
bool CWalletDB : : EraseWatchOnly ( const CScript & dest )
{
{
nWalletDBUpdateCounter + + ;
if ( ! EraseIC ( std : : make_pair ( std : : string ( " watchmeta " ) , * ( const CScriptBase * ) ( & dest ) ) ) ) {
if ( ! batch . Erase ( std : : make_pair ( std : : string ( " watchmeta " ) , * ( const CScriptBase * ) ( & dest ) ) ) )
return false ;
return false ;
return batch . Erase ( std : : make_pair ( std : : string ( " watchs " ) , * ( const CScriptBase * ) ( & dest ) ) ) ;
}
return EraseIC ( std : : make_pair ( std : : string ( " watchs " ) , * ( const CScriptBase * ) ( & dest ) ) ) ;
}
}
bool CWalletDB : : WriteBestBlock ( const CBlockLocator & locator )
bool CWalletDB : : WriteBestBlock ( const CBlockLocator & locator )
{
{
nWalletDBUpdateCounter + + ;
WriteIC ( std : : string ( " bestblock " ) , CBlockLocator ( ) ) ; // Write empty block locator so versions that require a merkle branch automatically rescan
batch . Write ( 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 batch . Write ( std : : string ( " bestblock_nomerkle " ) , locator ) ;
}
}
bool CWalletDB : : ReadBestBlock ( CBlockLocator & locator )
bool CWalletDB : : ReadBestBlock ( CBlockLocator & locator )
@ -148,14 +134,12 @@ bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
bool CWalletDB : : WriteOrderPosNext ( int64_t nOrderPosNext )
bool CWalletDB : : WriteOrderPosNext ( int64_t nOrderPosNext )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : string ( " orderposnext " ) , nOrderPosNext ) ;
return batch . Write ( std : : string ( " orderposnext " ) , nOrderPosNext ) ;
}
}
bool CWalletDB : : WriteDefaultKey ( const CPubKey & vchPubKey )
bool CWalletDB : : WriteDefaultKey ( const CPubKey & vchPubKey )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : string ( " defaultkey " ) , vchPubKey ) ;
return batch . Write ( std : : string ( " defaultkey " ) , vchPubKey ) ;
}
}
bool CWalletDB : : ReadPool ( int64_t nPool , CKeyPool & keypool )
bool CWalletDB : : ReadPool ( int64_t nPool , CKeyPool & keypool )
@ -165,19 +149,17 @@ bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool)
bool CWalletDB : : WritePool ( int64_t nPool , const CKeyPool & keypool )
bool CWalletDB : : WritePool ( int64_t nPool , const CKeyPool & keypool )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " pool " ) , nPool ) , keypool ) ;
return batch . Write ( std : : make_pair ( std : : string ( " pool " ) , nPool ) , keypool ) ;
}
}
bool CWalletDB : : ErasePool ( int64_t nPool )
bool CWalletDB : : ErasePool ( int64_t nPool )
{
{
nWalletDBUpdateCounter + + ;
return EraseIC ( std : : make_pair ( std : : string ( " pool " ) , nPool ) ) ;
return batch . Erase ( std : : make_pair ( std : : string ( " pool " ) , nPool ) ) ;
}
}
bool CWalletDB : : WriteMinVersion ( int nVersion )
bool CWalletDB : : WriteMinVersion ( int nVersion )
{
{
return batch . Write ( std : : string ( " minversion " ) , nVersion ) ;
return WriteIC ( std : : string ( " minversion " ) , nVersion ) ;
}
}
bool CWalletDB : : ReadAccount ( const std : : string & strAccount , CAccount & account )
bool CWalletDB : : ReadAccount ( const std : : string & strAccount , CAccount & account )
@ -188,17 +170,12 @@ bool CWalletDB::ReadAccount(const std::string& strAccount, CAccount& account)
bool CWalletDB : : WriteAccount ( const std : : string & strAccount , const CAccount & account )
bool CWalletDB : : WriteAccount ( const std : : string & strAccount , const CAccount & account )
{
{
return batch . Write ( 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 CWalletDB : : WriteAccountingEntry ( const uint64_t nAccEntryNum , const CAccountingEntry & acentry )
{
{
return batch . Write ( 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 ) ;
}
bool CWalletDB : : WriteAccountingEntry_Backend ( const CAccountingEntry & acentry )
{
return WriteAccountingEntry ( + + nAccountingEntryNumber , acentry ) ;
}
}
CAmount CWalletDB : : GetAccountCreditDebit ( const std : : string & strAccount )
CAmount CWalletDB : : GetAccountCreditDebit ( const std : : string & strAccount )
@ -337,8 +314,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
ssKey > > strAccount ;
ssKey > > strAccount ;
uint64_t nNumber ;
uint64_t nNumber ;
ssKey > > nNumber ;
ssKey > > nNumber ;
if ( nNumber > nAccountingEntryNumber )
if ( nNumber > pwallet - > nAccountingEntryNumber ) {
nAccountingEntryNumber = nNumber ;
pwallet - > nAccountingEntryNumber = nNumber ;
}
if ( ! wss . fAnyUnordered )
if ( ! wss . fAnyUnordered )
{
{
@ -784,38 +762,39 @@ void MaybeCompactWalletDB()
return ;
return ;
}
}
static unsigned int nLastSeen = CWalletDB : : GetUpdateCounter ( ) ;
for ( CWalletRef pwallet : vpwallets ) {
static unsigned int nLastFlushed = CWalletDB : : GetUpdateCounter ( ) ;
CWalletDBWrapper & dbh = pwallet - > GetDBHandle ( ) ;
static int64_t nLastWalletUpdate = GetTime ( ) ;
if ( nLastSeen ! = CWalletDB : : GetUpdateCounter ( ) )
unsigned int nUpdateCounter = dbh . nUpdateCounter ;
{
nLastSeen = CWalletDB : : GetUpdateCounter ( ) ;
nLastWalletUpdate = GetTime ( ) ;
}
if ( nLastFlushed ! = CWalletDB : : GetUpdateCounter ( ) & & GetTime ( ) - nLastWalletUpdate > = 2 )
if ( dbh . nLastSeen ! = nUpdateCounter ) {
{
dbh . nLastSeen = nUpdateCounter ;
if ( CDB : : PeriodicFlush ( pwalletMain - > GetDBHandle ( ) ) ) {
dbh . nLastWalletUpdate = GetTime ( ) ;
nLastFlushed = CWalletDB : : GetUpdateCounter ( ) ;
}
if ( dbh . nLastFlushed ! = nUpdateCounter & & GetTime ( ) - dbh . nLastWalletUpdate > = 2 ) {
if ( CDB : : PeriodicFlush ( dbh ) ) {
dbh . nLastFlushed = nUpdateCounter ;
}
}
}
}
}
fOneThread = false ;
fOneThread = false ;
}
}
//
//
// 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 std : : string & filename , void * callbackDataIn , bool ( * recoverKVcallback ) ( void * callbackData , CDataStream ssKey , CDataStream ssValue ) )
bool CWalletDB : : Recover ( const std : : string & filename , void * callbackDataIn , bool ( * recoverKVcallback ) ( void * callbackData , CDataStream ssKey , CDataStream ssValue ) , std : : string & out_backup_filename )
{
{
return CDB : : Recover ( filename , callbackDataIn , recoverKVcallback ) ;
return CDB : : Recover ( filename , callbackDataIn , recoverKVcallback , out_backup_filename ) ;
}
}
bool CWalletDB : : Recover ( const std : : string & filename )
bool CWalletDB : : Recover ( const std : : string & filename , 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 ( filename , NULL , NULL ) ;
return CWalletDB : : Recover ( filename , NULL , NULL , out_backup_filename ) ;
}
}
bool CWalletDB : : RecoverKeysOnlyFilter ( void * callbackData , CDataStream ssKey , CDataStream ssValue )
bool CWalletDB : : RecoverKeysOnlyFilter ( void * callbackData , CDataStream ssKey , CDataStream ssValue )
@ -848,36 +827,23 @@ bool CWalletDB::VerifyEnvironment(const std::string& walletFile, const fs::path&
bool CWalletDB : : VerifyDatabaseFile ( const std : : string & walletFile , const fs : : path & dataDir , std : : string & warningStr , std : : string & errorStr )
bool CWalletDB : : VerifyDatabaseFile ( const std : : string & walletFile , const fs : : path & dataDir , std : : string & warningStr , std : : string & errorStr )
{
{
return CDB : : VerifyDatabaseFile ( walletFile , dataDir , errorStr , warning Str, CWalletDB : : Recover ) ;
return CDB : : VerifyDatabaseFile ( walletFile , dataDir , warningStr , error Str, CWalletDB : : Recover ) ;
}
}
bool CWalletDB : : WriteDestData ( const std : : string & address , const std : : string & key , const std : : string & value )
bool CWalletDB : : WriteDestData ( const std : : string & address , const std : : string & key , const std : : string & value )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : make_pair ( std : : string ( " destdata " ) , std : : make_pair ( address , key ) ) , value ) ;
return batch . Write ( std : : make_pair ( std : : string ( " destdata " ) , std : : make_pair ( address , key ) ) , value ) ;
}
}
bool CWalletDB : : EraseDestData ( const std : : string & address , const std : : string & key )
bool CWalletDB : : EraseDestData ( const std : : string & address , const std : : string & key )
{
{
nWalletDBUpdateCounter + + ;
return EraseIC ( std : : make_pair ( std : : string ( " destdata " ) , std : : make_pair ( address , key ) ) ) ;
return batch . Erase ( std : : make_pair ( std : : string ( " destdata " ) , std : : make_pair ( address , key ) ) ) ;
}
}
bool CWalletDB : : WriteHDChain ( const CHDChain & chain )
bool CWalletDB : : WriteHDChain ( const CHDChain & chain )
{
{
nWalletDBUpdateCounter + + ;
return WriteIC ( std : : string ( " hdchain " ) , chain ) ;
return batch . Write ( std : : string ( " hdchain " ) , chain ) ;
}
void CWalletDB : : IncrementUpdateCounter ( )
{
nWalletDBUpdateCounter + + ;
}
unsigned int CWalletDB : : GetUpdateCounter ( )
{
return nWalletDBUpdateCounter ;
}
}
bool CWalletDB : : TxnBegin ( )
bool CWalletDB : : TxnBegin ( )