@ -297,7 +297,6 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
Lock ( ) ;
Lock ( ) ;
Unlock ( strWalletPassphrase ) ;
Unlock ( strWalletPassphrase ) ;
NewKeyPool ( ) ;
Lock ( ) ;
Lock ( ) ;
// 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
@ -321,65 +320,14 @@ int64 CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
return nRet ;
return nRet ;
}
}
CWallet : : TxItems CWallet : : OrderedTxItems ( std : : list < CAccountingEntry > & acentries , std : : string strAccount )
{
CWalletDB walletdb ( strWalletFile ) ;
// First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
TxItems txOrdered ;
// Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
// would make this much faster for applications that do this a lot.
for ( map < uint256 , CWalletTx > : : iterator it = mapWallet . begin ( ) ; it ! = mapWallet . end ( ) ; + + it )
{
CWalletTx * wtx = & ( ( * it ) . second ) ;
txOrdered . insert ( make_pair ( wtx - > nOrderPos , TxPair ( wtx , ( CAccountingEntry * ) 0 ) ) ) ;
}
acentries . clear ( ) ;
walletdb . ListAccountCreditDebit ( strAccount , acentries ) ;
BOOST_FOREACH ( CAccountingEntry & entry , acentries )
{
txOrdered . insert ( make_pair ( entry . nOrderPos , TxPair ( ( CWalletTx * ) 0 , & entry ) ) ) ;
}
return txOrdered ;
}
void CWallet : : WalletUpdateSpent ( const CTransaction & tx )
{
// Anytime a signature is successfully verified, it's proof the outpoint is spent.
// Update the wallet spent flag if it doesn't know due to wallet.dat being
// restored from backup or the user making copies of wallet.dat.
{
LOCK ( cs_wallet ) ;
/*
BOOST_FOREACH ( const CTxIn & txin , tx . vin )
{
map < uint256 , CWalletTx > : : iterator mi = mapWallet . find ( txin . prevout . hash ) ;
if ( mi ! = mapWallet . end ( ) )
{
CWalletTx & wtx = ( * mi ) . second ;
if ( txin . prevout . n > = wtx . vout . size ( ) )
printf ( " WalletUpdateSpent: bad wtx %s \n " , wtx . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
else if ( ! wtx . IsSpent ( txin . prevout . n ) & & IsMine ( wtx . vout [ txin . prevout . n ] ) )
{
printf ( " WalletUpdateSpent found spent coin %sbc %s \n " , FormatMoney ( wtx . GetCredit ( ) ) . c_str ( ) , wtx . GetHash ( ) . ToString ( ) . c_str ( ) ) ;
wtx . MarkSpent ( txin . prevout . n ) ;
wtx . WriteToDisk ( ) ;
NotifyTransactionChanged ( this , txin . prevout . hash , CT_UPDATED ) ;
}
}
}
*/
}
}
void CWallet : : MarkDirty ( )
void CWallet : : MarkDirty ( )
{
{
{
{
LOCK ( cs_wallet ) ;
LOCK ( cs_wallet ) ;
/*
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CWalletTx ) & item , mapWallet )
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CWalletTx ) & item , mapWallet )
item . second . MarkDirty ( ) ;
item . second . MarkDirty ( ) ;
*/
}
}
}
}
@ -403,40 +351,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
{
if ( mapBlockIndex . count ( wtxIn . hashBlock ) )
if ( mapBlockIndex . count ( wtxIn . hashBlock ) )
{
{
unsigned int latestNow = wtx . nTimeReceived ;
unsigned int latestEntry = 0 ;
{
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64 latestTolerated = latestNow + 300 ;
std : : list < CAccountingEntry > acentries ;
TxItems txOrdered = OrderedTxItems ( acentries ) ;
for ( TxItems : : reverse_iterator it = txOrdered . rbegin ( ) ; it ! = txOrdered . rend ( ) ; + + it )
{
CWalletTx * const pwtx = ( * it ) . second . first ;
if ( pwtx = = & wtx )
continue ;
CAccountingEntry * const pacentry = ( * it ) . second . second ;
int64 nSmartTime ;
if ( pwtx )
{
nSmartTime = pwtx - > nTimeSmart ;
if ( ! nSmartTime )
nSmartTime = pwtx - > nTimeReceived ;
}
else
nSmartTime = pacentry - > nTime ;
if ( nSmartTime < = latestTolerated )
{
latestEntry = nSmartTime ;
if ( nSmartTime > latestNow )
latestNow = nSmartTime ;
break ;
}
}
}
unsigned int & blocktime = mapBlockIndex [ wtxIn . hashBlock ] - > nTime ;
unsigned int & blocktime = mapBlockIndex [ wtxIn . hashBlock ] - > nTime ;
wtx . nTimeSmart = std : : max ( latestEntry , std : : min ( blocktime , latestNow ) ) ;
wtx . nTimeSmart = blocktime ;
}
}
else
else
printf ( " AddToWallet() : found %s in block %s not in index \n " ,
printf ( " AddToWallet() : found %s in block %s not in index \n " ,
@ -465,7 +381,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
wtx . fFromMe = wtxIn . fFromMe ;
wtx . fFromMe = wtxIn . fFromMe ;
fUpdated = true ;
fUpdated = true ;
}
}
fUpdated | = wtx . UpdateSpent ( wtxIn . vfSpent ) ;
}
}
//// debug print
//// debug print
@ -497,8 +412,6 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
*/
*/
}
}
}
}
// since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
WalletUpdateSpent ( wtx ) ;
// Notify UI of new or updated transaction
// Notify UI of new or updated transaction
NotifyTransactionChanged ( this , hash , fInsertedNew ? CT_NEW : CT_UPDATED ) ;
NotifyTransactionChanged ( this , hash , fInsertedNew ? CT_NEW : CT_UPDATED ) ;
@ -533,8 +446,6 @@ bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction&
wtx . SetMerkleBranch ( pblock ) ;
wtx . SetMerkleBranch ( pblock ) ;
return AddToWallet ( wtx ) ;
return AddToWallet ( wtx ) ;
}
}
else
WalletUpdateSpent ( tx ) ;
}
}
return false ;
return false ;
}
}
@ -552,62 +463,6 @@ bool CWallet::EraseFromWallet(uint256 hash)
}
}
bool CWallet : : IsMine ( const CTxIn & txin ) const
{
{
LOCK ( cs_wallet ) ;
map < uint256 , CWalletTx > : : const_iterator mi = mapWallet . find ( txin . prevout . hash ) ;
if ( mi ! = mapWallet . end ( ) )
{
const CWalletTx & prev = ( * mi ) . second ;
/*
if ( txin . prevout . n < prev . vout . size ( ) )
if ( IsMine ( prev . vout [ txin . prevout . n ] ) )
return true ;
*/
}
}
return false ;
}
int64 CWallet : : GetDebit ( const CTxIn & txin ) const
{
{
LOCK ( cs_wallet ) ;
map < uint256 , CWalletTx > : : const_iterator mi = mapWallet . find ( txin . prevout . hash ) ;
if ( mi ! = mapWallet . end ( ) )
{
const CWalletTx & prev = ( * mi ) . second ;
/*
if ( txin . prevout . n < prev . vout . size ( ) )
if ( IsMine ( prev . vout [ txin . prevout . n ] ) )
return prev . vout [ txin . prevout . n ] . nValue ;
*/
}
}
return 0 ;
}
bool CWallet : : IsChange ( const CTxOut & txout ) const
{
CTxDestination address ;
// TODO: fix handling of 'change' outputs. The assumption is that any
// payment to a TX_PUBKEYHASH that is mine but isn't in the address book
// is change. That assumption is likely to break when we implement multisignature
// wallets that return change back into a multi-signature-protected address;
// a better way of identifying which outputs are 'the send' and which are
// 'the change' will need to be implemented (maybe extend CWalletTx to remember
// which output, if any, was change).
if ( ExtractDestination ( txout . scriptPubKey , address ) & & : : IsMine ( * this , address ) )
{
LOCK ( cs_wallet ) ;
if ( ! mapAddressBook . count ( address ) )
return true ;
}
return false ;
}
int64 CWalletTx : : GetTxTime ( ) const
int64 CWalletTx : : GetTxTime ( ) const
{
{
int64 n = nTimeSmart ;
int64 n = nTimeSmart ;
@ -707,7 +562,7 @@ void CWallet::ReacceptWalletTransactions()
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CWalletTx ) & item , mapWallet )
BOOST_FOREACH ( PAIRTYPE ( const uint256 , CWalletTx ) & item , mapWallet )
{
{
CWalletTx & wtx = item . second ;
CWalletTx & wtx = item . second ;
if ( wtx . IsSpamMessage ( ) & & wtx . IsSpent ( 0 ) )
if ( wtx . IsSpamMessage ( ) )
continue ;
continue ;
CTransaction tx ;
CTransaction tx ;
@ -817,63 +672,6 @@ void CWallet::ResendWalletTransactions()
// Actions
// Actions
//
//
int64 CWallet : : GetBalance ( ) const
{
int64 nTotal = 0 ;
{
LOCK ( cs_wallet ) ;
for ( map < uint256 , CWalletTx > : : const_iterator it = mapWallet . begin ( ) ; it ! = mapWallet . end ( ) ; + + it )
{
const CWalletTx * pcoin = & ( * it ) . second ;
if ( pcoin - > IsConfirmed ( ) )
nTotal + = pcoin - > GetAvailableCredit ( ) ;
}
}
return nTotal ;
}
int64 CWallet : : GetUnconfirmedBalance ( ) const
{
int64 nTotal = 0 ;
return nTotal ;
}
int64 CWallet : : GetImmatureBalance ( ) const
{
int64 nTotal = 0 ;
return nTotal ;
}
// populate vCoins with vector of spendable COutputs
void CWallet : : AvailableCoins ( vector < COutput > & vCoins , bool fOnlyConfirmed ) const
{
vCoins . clear ( ) ;
{
LOCK ( cs_wallet ) ;
for ( map < uint256 , CWalletTx > : : const_iterator it = mapWallet . begin ( ) ; it ! = mapWallet . end ( ) ; + + it )
{
const CWalletTx * pcoin = & ( * it ) . second ;
if ( fOnlyConfirmed & & ! pcoin - > IsConfirmed ( ) )
continue ;
if ( pcoin - > IsSpamMessage ( ) & & pcoin - > GetBlocksToMaturity ( ) > 0 )
continue ;
/*
for ( unsigned int i = 0 ; i < pcoin - > vout . size ( ) ; i + + ) {
if ( ! ( pcoin - > IsSpent ( i ) ) & & IsMine ( pcoin - > vout [ i ] ) & &
! IsLockedCoin ( ( * it ) . first , i ) & & pcoin - > vout [ i ] . nValue > 0 )
vCoins . push_back ( COutput ( pcoin , i , pcoin - > GetDepthInMainChain ( ) ) ) ;
}
*/
}
}
}
bool CWallet : : CreateTransaction ( const vector < pair < CScript , int64 > > & vecSend ,
bool CWallet : : CreateTransaction ( const vector < pair < CScript , int64 > > & vecSend ,
CWalletTx & wtxNew , CReserveKey & reservekey , int64 & nFeeRet , std : : string & strFailReason )
CWalletTx & wtxNew , CReserveKey & reservekey , int64 & nFeeRet , std : : string & strFailReason )
{
{
@ -1106,8 +904,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
string strError ;
string strError ;
if ( ! CreateTransaction ( scriptPubKey , nValue , wtxNew , reservekey , nFeeRequired , strError ) )
if ( ! CreateTransaction ( scriptPubKey , nValue , wtxNew , reservekey , nFeeRequired , strError ) )
{
{
if ( nValue + nFeeRequired > GetBalance ( ) )
strError = strprintf ( _ ( " Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds! " ) , FormatMoney ( nFeeRequired ) . c_str ( ) ) ;
printf ( " SendMoney() : %s \n " , strError . c_str ( ) ) ;
printf ( " SendMoney() : %s \n " , strError . c_str ( ) ) ;
return strError ;
return strError ;
}
}
@ -1123,24 +919,6 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
string CWallet : : SendMoneyToDestination ( const CTxDestination & address , int64 nValue , CWalletTx & wtxNew , bool fAskFee )
{
// Check amount
if ( nValue < = 0 )
return _ ( " Invalid amount " ) ;
if ( nValue + nTransactionFee > GetBalance ( ) )
return _ ( " Insufficient funds " ) ;
// Parse Bitcoin address
CScript scriptPubKey ;
scriptPubKey . SetDestination ( address ) ;
return SendMoney ( scriptPubKey , nValue , wtxNew , fAskFee ) ;
}
DBErrors CWallet : : LoadWallet ( bool & fFirstRunRet )
DBErrors CWallet : : LoadWallet ( bool & fFirstRunRet )
{
{
if ( ! fFileBacked )
if ( ! fFileBacked )
@ -1186,33 +964,6 @@ bool CWallet::DelAddressBookName(const CTxDestination& address)
}
}
void CWallet : : PrintWallet ( const CBlock & block )
{
{
LOCK ( cs_wallet ) ;
if ( mapWallet . count ( block . vtx [ 0 ] . GetHash ( ) ) )
{
CWalletTx & wtx = mapWallet [ block . vtx [ 0 ] . GetHash ( ) ] ;
printf ( " mine: %d %d % " PRI64d " " , wtx . GetDepthInMainChain ( ) , wtx . GetBlocksToMaturity ( ) , wtx . GetCredit ( ) ) ;
}
}
printf ( " \n " ) ;
}
bool CWallet : : GetTransaction ( const uint256 & hashTx , CWalletTx & wtx )
{
{
LOCK ( cs_wallet ) ;
map < uint256 , CWalletTx > : : iterator mi = mapWallet . find ( hashTx ) ;
if ( mi ! = mapWallet . end ( ) )
{
wtx = ( * mi ) . second ;
return true ;
}
}
return false ;
}
bool CWallet : : SetDefaultKey ( const CPubKey & vchPubKey )
bool CWallet : : SetDefaultKey ( const CPubKey & vchPubKey )
{
{
if ( fFileBacked )
if ( fFileBacked )
@ -1232,63 +983,6 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
return true ;
return true ;
}
}
//
// Mark old keypool keys as used,
// and generate all new keys
//
bool CWallet : : NewKeyPool ( )
{
/*
{
LOCK ( cs_wallet ) ;
CWalletDB walletdb ( strWalletFile ) ;
BOOST_FOREACH ( int64 nIndex , setKeyPool )
walletdb . ErasePool ( nIndex ) ;
setKeyPool . clear ( ) ;
if ( IsLocked ( ) )
return false ;
int64 nKeys = max ( GetArg ( " -keypool " , 100 ) , ( int64 ) 0 ) ;
for ( int i = 0 ; i < nKeys ; i + + )
{
int64 nIndex = i + 1 ;
walletdb . WritePool ( nIndex , CKeyPool ( GenerateNewKey ( ) ) ) ;
setKeyPool . insert ( nIndex ) ;
}
printf ( " CWallet::NewKeyPool wrote % " PRI64d " new keys \n " , nKeys ) ;
}
*/
return true ;
}
bool CWallet : : TopUpKeyPool ( )
{
/*
{
LOCK ( cs_wallet ) ;
if ( IsLocked ( ) )
return false ;
CWalletDB walletdb ( strWalletFile ) ;
// Top up key pool
unsigned int nTargetSize = max ( GetArg ( " -keypool " , 100 ) , 0LL ) ;
while ( setKeyPool . size ( ) < ( nTargetSize + 1 ) )
{
int64 nEnd = 1 ;
if ( ! setKeyPool . empty ( ) )
nEnd = * ( - - setKeyPool . end ( ) ) + 1 ;
if ( ! walletdb . WritePool ( nEnd , CKeyPool ( GenerateNewKey ( ) ) ) )
throw runtime_error ( " TopUpKeyPool() : writing generated key failed " ) ;
setKeyPool . insert ( nEnd ) ;
printf ( " keypool added key % " PRI64d " , size=% " PRIszu " \n " , nEnd , setKeyPool . size ( ) ) ;
}
}
*/
return true ;
}
void CWallet : : ReserveKeyFromKeyPool ( int64 & nIndex , CKeyPool & keypool )
void CWallet : : ReserveKeyFromKeyPool ( int64 & nIndex , CKeyPool & keypool )
{
{
@ -1297,9 +991,6 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
{
{
LOCK ( cs_wallet ) ;
LOCK ( cs_wallet ) ;
if ( ! IsLocked ( ) )
TopUpKeyPool ( ) ;
// Get the oldest key
// Get the oldest key
if ( setKeyPool . empty ( ) )
if ( setKeyPool . empty ( ) )
return ;
return ;
@ -1391,47 +1082,6 @@ int64 CWallet::GetOldestKeyPoolTime()
return keypool . nTime ;
return keypool . nTime ;
}
}
std : : map < CTxDestination , int64 > CWallet : : GetAddressBalances ( )
{
map < CTxDestination , int64 > balances ;
{
LOCK ( cs_wallet ) ;
BOOST_FOREACH ( PAIRTYPE ( uint256 , CWalletTx ) walletEntry , mapWallet )
{
CWalletTx * pcoin = & walletEntry . second ;
if ( ! pcoin - > IsConfirmed ( ) )
continue ;
if ( pcoin - > IsSpamMessage ( ) & & pcoin - > GetBlocksToMaturity ( ) > 0 )
continue ;
int nDepth = pcoin - > GetDepthInMainChain ( ) ;
if ( nDepth < ( pcoin - > IsFromMe ( ) ? 0 : 1 ) )
continue ;
/*
for ( unsigned int i = 0 ; i < pcoin - > vout . size ( ) ; i + + )
{
CTxDestination addr ;
if ( ! IsMine ( pcoin - > vout [ i ] ) )
continue ;
if ( ! ExtractDestination ( pcoin - > vout [ i ] . scriptPubKey , addr ) )
continue ;
int64 n = pcoin - > IsSpent ( i ) ? 0 : pcoin - > vout [ i ] . nValue ;
if ( ! balances . count ( addr ) )
balances [ addr ] = 0 ;
balances [ addr ] + = n ;
} */
}
}
return balances ;
}
set < set < CTxDestination > > CWallet : : GetAddressGroupings ( )
set < set < CTxDestination > > CWallet : : GetAddressGroupings ( )
{
{
set < set < CTxDestination > > groupings ;
set < set < CTxDestination > > groupings ;
@ -1593,36 +1243,6 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx)
}
}
}
}
void CWallet : : LockCoin ( COutPoint & output )
{
setLockedCoins . insert ( output ) ;
}
void CWallet : : UnlockCoin ( COutPoint & output )
{
setLockedCoins . erase ( output ) ;
}
void CWallet : : UnlockAllCoins ( )
{
setLockedCoins . clear ( ) ;
}
bool CWallet : : IsLockedCoin ( uint256 hash , unsigned int n ) const
{
COutPoint outpt ( hash , n ) ;
return ( setLockedCoins . count ( outpt ) > 0 ) ;
}
void CWallet : : ListLockedCoins ( std : : vector < COutPoint > & vOutpts )
{
for ( std : : set < COutPoint > : : iterator it = setLockedCoins . begin ( ) ;
it ! = setLockedCoins . end ( ) ; it + + ) {
COutPoint outpt = ( * it ) ;
vOutpts . push_back ( outpt ) ;
}
}
void CWallet : : GetKeyBirthTimes ( std : : map < CKeyID , int64 > & mapKeyBirth ) const {
void CWallet : : GetKeyBirthTimes ( std : : map < CKeyID , int64 > & mapKeyBirth ) const {
mapKeyBirth . clear ( ) ;
mapKeyBirth . clear ( ) ;