@ -33,6 +33,7 @@
using namespace std ;
using namespace std ;
CWallet * pwalletMain = NULL ;
/** Transaction fee set by the user */
/** Transaction fee set by the user */
CFeeRate payTxFee ( DEFAULT_TRANSACTION_FEE ) ;
CFeeRate payTxFee ( DEFAULT_TRANSACTION_FEE ) ;
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET ;
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET ;
@ -364,8 +365,33 @@ void CWallet::Flush(bool shutdown)
bitdb . Flush ( shutdown ) ;
bitdb . Flush ( shutdown ) ;
}
}
bool CWallet : : Verify ( const string & walletFile , string & warningString , string & errorString )
bool static UIError ( const std : : string & str )
{
{
uiInterface . ThreadSafeMessageBox ( str , " " , CClientUIInterface : : MSG_ERROR ) ;
return false ;
}
void static UIWarning ( const std : : string & str )
{
uiInterface . ThreadSafeMessageBox ( str , " " , CClientUIInterface : : MSG_WARNING ) ;
}
static std : : string AmountErrMsg ( const char * const optname , const std : : string & strValue )
{
return strprintf ( _ ( " Invalid amount for -%s=<amount>: '%s' " ) , optname , strValue ) ;
}
bool CWallet : : Verify ( )
{
std : : string walletFile = GetArg ( " -wallet " , DEFAULT_WALLET_DAT ) ;
LogPrintf ( " Using wallet %s \n " , walletFile ) ;
uiInterface . InitMessage ( _ ( " Verifying wallet... " ) ) ;
// Wallet file must be a plain filename without a directory
if ( walletFile ! = boost : : filesystem : : basename ( walletFile ) + boost : : filesystem : : extension ( walletFile ) )
return UIError ( strprintf ( _ ( " Wallet %s resides outside data directory %s " ) , walletFile , GetDataDir ( ) . string ( ) ) ) ;
if ( ! bitdb . Open ( GetDataDir ( ) ) )
if ( ! bitdb . Open ( GetDataDir ( ) ) )
{
{
// try moving the database env out of the way
// try moving the database env out of the way
@ -381,9 +407,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
// try again
// try again
if ( ! bitdb . Open ( GetDataDir ( ) ) ) {
if ( ! bitdb . Open ( GetDataDir ( ) ) ) {
// if it still fails, it probably means we can't even create the database env
// if it still fails, it probably means we can't even create the database env
string msg = strprintf ( _ ( " Error initializing wallet database environment %s! " ) , GetDataDir ( ) ) ;
return UIError ( strprintf ( _ ( " Error initializing wallet database environment %s! " ) , GetDataDir ( ) ) ) ;
errorString + = msg ;
return true ;
}
}
}
}
@ -399,14 +423,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
CDBEnv : : VerifyResult r = bitdb . Verify ( walletFile , CWalletDB : : Recover ) ;
CDBEnv : : VerifyResult r = bitdb . Verify ( walletFile , CWalletDB : : Recover ) ;
if ( r = = CDBEnv : : RECOVER_OK )
if ( r = = CDBEnv : : RECOVER_OK )
{
{
warningString + = strprintf ( _ ( " Warning: Wallet file corrupt, data salvaged! "
UIWarning ( strprintf ( _ ( " Warning: Wallet file corrupt, data salvaged! "
" Original %s saved as %s in %s; if "
" Original %s saved as %s in %s; if "
" your balance or transactions are incorrect you should "
" your balance or transactions are incorrect you should "
" restore from a backup. " ) ,
" restore from a backup. " ) ,
walletFile , " wallet.{timestamp}.bak " , GetDataDir ( ) ) ;
walletFile , " wallet.{timestamp}.bak " , GetDataDir ( ) ) ) ;
}
}
if ( r = = CDBEnv : : RECOVER_FAIL )
if ( r = = CDBEnv : : RECOVER_FAIL )
errorString + = strprintf ( _ ( " %s corrupt, salvage failed " ) , walletFile ) ;
return UIError ( strprintf ( _ ( " %s corrupt, salvage failed " ) , walletFile ) ) ;
}
}
return true ;
return true ;
@ -2992,20 +3016,20 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
return strUsage ;
return strUsage ;
}
}
CWallet * CWallet : : InitLoadWallet ( bool fDisableWallet , const std : : string & strWalletFile , std : : string & warningString , std : : string & errorString )
bool CWallet : : InitLoadWallet ( )
{
{
std : : string walletFile = GetArg ( " -wallet " , DEFAULT_WALLET_DAT ) ;
// needed to restore wallet transaction meta data after -zapwallettxes
// needed to restore wallet transaction meta data after -zapwallettxes
std : : vector < CWalletTx > vWtx ;
std : : vector < CWalletTx > vWtx ;
if ( GetBoolArg ( " -zapwallettxes " , false ) ) {
if ( GetBoolArg ( " -zapwallettxes " , false ) ) {
uiInterface . InitMessage ( _ ( " Zapping all transactions from wallet... " ) ) ;
uiInterface . InitMessage ( _ ( " Zapping all transactions from wallet... " ) ) ;
CWallet * tempWallet = new CWallet ( strW alletFile) ;
CWallet * tempWallet = new CWallet ( w alletFile) ;
DBErrors nZapWalletRet = tempWallet - > ZapWalletTx ( vWtx ) ;
DBErrors nZapWalletRet = tempWallet - > ZapWalletTx ( vWtx ) ;
if ( nZapWalletRet ! = DB_LOAD_OK ) {
if ( nZapWalletRet ! = DB_LOAD_OK ) {
errorString = strprintf ( _ ( " Error loading %s: Wallet corrupted " ) , strWalletFile ) ;
return UIError ( strprintf ( _ ( " Error loading %s: Wallet corrupted " ) , walletFile ) ) ;
uiInterface . InitMessage ( strprintf ( _ ( " Error loading %s: Wallet corrupted " ) , strWalletFile ) ) ;
return NULL ;
}
}
delete tempWallet ;
delete tempWallet ;
@ -3016,32 +3040,27 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
int64_t nStart = GetTimeMillis ( ) ;
int64_t nStart = GetTimeMillis ( ) ;
bool fFirstRun = true ;
bool fFirstRun = true ;
CWallet * walletInstance = new CWallet ( strW alletFile) ;
CWallet * walletInstance = new CWallet ( w alletFile) ;
DBErrors nLoadWalletRet = walletInstance - > LoadWallet ( fFirstRun ) ;
DBErrors nLoadWalletRet = walletInstance - > LoadWallet ( fFirstRun ) ;
if ( nLoadWalletRet ! = DB_LOAD_OK )
if ( nLoadWalletRet ! = DB_LOAD_OK )
{
{
if ( nLoadWalletRet = = DB_CORRUPT )
if ( nLoadWalletRet = = DB_CORRUPT )
errorString + = strprintf ( _ ( " Error loading %s: Wallet corrupted " ) , strWalletFile ) + " \n " ;
return UIError ( strprintf ( _ ( " Error loading %s: Wallet corrupted " ) , walletFile ) ) ;
else if ( nLoadWalletRet = = DB_NONCRITICAL_ERROR )
else if ( nLoadWalletRet = = DB_NONCRITICAL_ERROR )
{
{
warningString + = strprintf ( _ ( " Error reading %s! All keys read correctly, but transaction data "
UIWarning ( strprintf ( _ ( " Error reading %s! All keys read correctly, but transaction data "
" or address book entries might be missing or incorrect. " ) ,
" or address book entries might be missing or incorrect. " ) ,
strWalletFile ) ;
walletFile ) ) ;
}
}
else if ( nLoadWalletRet = = DB_TOO_NEW )
else if ( nLoadWalletRet = = DB_TOO_NEW )
errorString + = strprintf ( _ ( " Error loading %s: Wallet requires newer version of %s " ) ,
return UIError ( strprintf ( _ ( " Error loading %s: Wallet requires newer version of %s " ) ,
strWalletFile , _ ( PACKAGE_NAME ) ) +
walletFile , _ ( PACKAGE_NAME ) ) ) ;
" \n " ;
else if ( nLoadWalletRet = = DB_NEED_REWRITE )
else if ( nLoadWalletRet = = DB_NEED_REWRITE )
{
{
errorString + = strprintf ( _ ( " Wallet needed to be rewritten: restart %s to complete " ) , _ ( PACKAGE_NAME ) ) + " \n " ;
return UIError ( strprintf ( _ ( " Wallet needed to be rewritten: restart %s to complete " ) , _ ( PACKAGE_NAME ) ) ) ;
LogPrintf ( " %s " , errorString ) ;
}
}
else
else
errorString + = strprintf ( _ ( " Error loading %s " ) , strWalletFile ) + " \n " ;
return UIError ( strprintf ( _ ( " Error loading %s " ) , walletFile ) ) ;
if ( ! errorString . empty ( ) )
return NULL ;
}
}
if ( GetBoolArg ( " -upgradewallet " , fFirstRun ) )
if ( GetBoolArg ( " -upgradewallet " , fFirstRun ) )
@ -3057,8 +3076,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
LogPrintf ( " Allowing wallet upgrade up to %i \n " , nMaxVersion ) ;
LogPrintf ( " Allowing wallet upgrade up to %i \n " , nMaxVersion ) ;
if ( nMaxVersion < walletInstance - > GetVersion ( ) )
if ( nMaxVersion < walletInstance - > GetVersion ( ) )
{
{
errorString + = _ ( " Cannot downgrade wallet " ) + " \n " ;
return UIError ( _ ( " Cannot downgrade wallet " ) ) ;
return NULL ;
}
}
walletInstance - > SetMaxVersion ( nMaxVersion ) ;
walletInstance - > SetMaxVersion ( nMaxVersion ) ;
}
}
@ -3072,10 +3090,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
if ( walletInstance - > GetKeyFromPool ( newDefaultKey ) ) {
if ( walletInstance - > GetKeyFromPool ( newDefaultKey ) ) {
walletInstance - > SetDefaultKey ( newDefaultKey ) ;
walletInstance - > SetDefaultKey ( newDefaultKey ) ;
if ( ! walletInstance - > SetAddressBook ( walletInstance - > vchDefaultKey . GetID ( ) , " " , " receive " ) )
if ( ! walletInstance - > SetAddressBook ( walletInstance - > vchDefaultKey . GetID ( ) , " " , " receive " ) )
{
return UIError ( _ ( " Cannot write default address " ) + = " \n " ) ;
errorString + = _ ( " Cannot write default address " ) + = " \n " ;
return NULL ;
}
}
}
walletInstance - > SetBestChain ( chainActive . GetLocator ( ) ) ;
walletInstance - > SetBestChain ( chainActive . GetLocator ( ) ) ;
@ -3090,7 +3105,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
pindexRescan = chainActive . Genesis ( ) ;
pindexRescan = chainActive . Genesis ( ) ;
else
else
{
{
CWalletDB walletdb ( strW alletFile) ;
CWalletDB walletdb ( w alletFile) ;
CBlockLocator locator ;
CBlockLocator locator ;
if ( walletdb . ReadBestBlock ( locator ) )
if ( walletdb . ReadBestBlock ( locator ) )
pindexRescan = FindForkInGlobalIndex ( chainActive , locator ) ;
pindexRescan = FindForkInGlobalIndex ( chainActive , locator ) ;
@ -3109,10 +3124,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
block = block - > pprev ;
block = block - > pprev ;
if ( pindexRescan ! = block )
if ( pindexRescan ! = block )
{
return UIError ( _ ( " Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) " )) ;
errorString = _ ( " Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) " ) ;
return NULL ;
}
}
}
uiInterface . InitMessage ( _ ( " Rescanning... " ) ) ;
uiInterface . InitMessage ( _ ( " Rescanning... " ) ) ;
@ -3126,7 +3138,7 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
// Restore wallet transaction metadata after -zapwallettxes=1
// Restore wallet transaction metadata after -zapwallettxes=1
if ( GetBoolArg ( " -zapwallettxes " , false ) & & GetArg ( " -zapwallettxes " , " 1 " ) ! = " 2 " )
if ( GetBoolArg ( " -zapwallettxes " , false ) & & GetArg ( " -zapwallettxes " , " 1 " ) ! = " 2 " )
{
{
CWalletDB walletdb ( strW alletFile) ;
CWalletDB walletdb ( w alletFile) ;
BOOST_FOREACH ( const CWalletTx & wtxOld , vWtx )
BOOST_FOREACH ( const CWalletTx & wtxOld , vWtx )
{
{
@ -3150,7 +3162,62 @@ CWallet* CWallet::InitLoadWallet(bool fDisableWallet, const std::string& strWall
}
}
walletInstance - > SetBroadcastTransactions ( GetBoolArg ( " -walletbroadcast " , DEFAULT_WALLETBROADCAST ) ) ;
walletInstance - > SetBroadcastTransactions ( GetBoolArg ( " -walletbroadcast " , DEFAULT_WALLETBROADCAST ) ) ;
return walletInstance ;
pwalletMain = walletInstance ;
return true ;
}
bool CWallet : : ParameterInteraction ( )
{
if ( mapArgs . count ( " -mintxfee " ) )
{
CAmount n = 0 ;
if ( ParseMoney ( mapArgs [ " -mintxfee " ] , n ) & & n > 0 )
CWallet : : minTxFee = CFeeRate ( n ) ;
else
return UIError ( AmountErrMsg ( " mintxfee " , mapArgs [ " -mintxfee " ] ) ) ;
}
if ( mapArgs . count ( " -fallbackfee " ) )
{
CAmount nFeePerK = 0 ;
if ( ! ParseMoney ( mapArgs [ " -fallbackfee " ] , nFeePerK ) )
return UIError ( strprintf ( _ ( " Invalid amount for -fallbackfee=<amount>: '%s' " ) , mapArgs [ " -fallbackfee " ] ) ) ;
if ( nFeePerK > HIGH_TX_FEE_PER_KB )
UIWarning ( _ ( " -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available. " ) ) ;
CWallet : : fallbackFee = CFeeRate ( nFeePerK ) ;
}
if ( mapArgs . count ( " -paytxfee " ) )
{
CAmount nFeePerK = 0 ;
if ( ! ParseMoney ( mapArgs [ " -paytxfee " ] , nFeePerK ) )
return UIError ( AmountErrMsg ( " paytxfee " , mapArgs [ " -paytxfee " ] ) ) ;
if ( nFeePerK > HIGH_TX_FEE_PER_KB )
UIWarning ( _ ( " -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. " ) ) ;
payTxFee = CFeeRate ( nFeePerK , 1000 ) ;
if ( payTxFee < : : minRelayTxFee )
{
return UIError ( strprintf ( _ ( " Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) " ) ,
mapArgs [ " -paytxfee " ] , : : minRelayTxFee . ToString ( ) ) ) ;
}
}
if ( mapArgs . count ( " -maxtxfee " ) )
{
CAmount nMaxFee = 0 ;
if ( ! ParseMoney ( mapArgs [ " -maxtxfee " ] , nMaxFee ) )
return UIError ( AmountErrMsg ( " maxtxfee " , mapArgs [ " -maxtxfee " ] ) ) ;
if ( nMaxFee > HIGH_MAX_TX_FEE )
UIWarning ( _ ( " -maxtxfee is set very high! Fees this large could be paid on a single transaction. " ) ) ;
maxTxFee = nMaxFee ;
if ( CFeeRate ( maxTxFee , 1000 ) < : : minRelayTxFee )
{
return UIError ( strprintf ( _ ( " Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) " ) ,
mapArgs [ " -maxtxfee " ] , : : minRelayTxFee . ToString ( ) ) ) ;
}
}
nTxConfirmTarget = GetArg ( " -txconfirmtarget " , DEFAULT_TX_CONFIRM_TARGET ) ;
bSpendZeroConfChange = GetBoolArg ( " -spendzeroconfchange " , DEFAULT_SPEND_ZEROCONF_CHANGE ) ;
fSendFreeTransactions = GetBoolArg ( " -sendfreetransactions " , DEFAULT_SEND_FREE_TRANSACTIONS ) ;
return true ;
}
}
CKeyPool : : CKeyPool ( )
CKeyPool : : CKeyPool ( )