aboutsummaryrefslogtreecommitdiff
path: root/src/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet.cpp')
-rw-r--r--src/wallet.cpp131
1 files changed, 75 insertions, 56 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 88b07c9d76..03d79406d8 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -159,7 +159,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
if (pMasterKey.second.nDeriveIterations < 25000)
pMasterKey.second.nDeriveIterations = 25000;
- printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
+ LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
return false;
@@ -267,7 +267,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
if (kMasterKey.nDeriveIterations < 25000)
kMasterKey.nDeriveIterations = 25000;
- printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
+ LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
return false;
@@ -368,10 +368,10 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx)
{
CWalletTx& wtx = (*mi).second;
if (txin.prevout.n >= wtx.vout.size())
- printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
+ LogPrintf("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());
+ LogPrintf("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);
@@ -446,9 +446,9 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
}
else
- printf("AddToWallet() : found %s in block %s not in index\n",
- wtxIn.GetHash().ToString().c_str(),
- wtxIn.hashBlock.ToString().c_str());
+ LogPrintf("AddToWallet() : found %s in block %s not in index\n",
+ wtxIn.GetHash().ToString().c_str(),
+ wtxIn.hashBlock.ToString().c_str());
}
}
@@ -476,7 +476,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
}
//// debug print
- printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
+ LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
// Write to disk
if (fInsertedNew || fUpdated)
@@ -493,10 +493,10 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
if (txout.scriptPubKey == scriptDefaultKey)
{
CPubKey newDefaultKey;
- if (GetKeyFromPool(newDefaultKey, false))
+ if (GetKeyFromPool(newDefaultKey))
{
SetDefaultKey(newDefaultKey);
- SetAddressBookName(vchDefaultKey.GetID(), "");
+ SetAddressBook(vchDefaultKey.GetID(), "", "receive");
}
}
}
@@ -677,8 +677,8 @@ void CWalletTx::GetAmounts(list<pair<CTxDestination, int64> >& listReceived,
vector<unsigned char> vchPubKey;
if (!ExtractDestination(txout.scriptPubKey, address))
{
- printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
- this->GetHash().ToString().c_str());
+ LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
+ this->GetHash().ToString().c_str());
}
// Don't report 'change' txouts
@@ -717,8 +717,8 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nReceived,
{
if (pwallet->mapAddressBook.count(r.first))
{
- map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
- if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
+ map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
+ if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
nReceived += r.second;
}
else if (strAccount.empty())
@@ -799,7 +799,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
// no need to read and scan block, if block was created before
// our wallet birthday (as adjusted for block time variability)
if (nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200))) {
- pindex = pindex->GetNextInMainChain();
+ pindex = chainActive.Next(pindex);
continue;
}
@@ -810,7 +810,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate))
ret++;
}
- pindex = pindex->GetNextInMainChain();
+ pindex = chainActive.Next(pindex);
}
}
return ret;
@@ -849,7 +849,7 @@ void CWallet::ReacceptWalletTransactions()
}
if (fUpdated)
{
- printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
+ LogPrintf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
wtx.MarkDirty();
wtx.WriteToDisk();
}
@@ -864,7 +864,7 @@ void CWallet::ReacceptWalletTransactions()
if (fMissing)
{
// TODO: optimize this to scan just part of the block chain?
- if (ScanForWalletTransactions(pindexGenesisBlock))
+ if (ScanForWalletTransactions(chainActive.Genesis()))
fRepeat = true; // Found missing transactions: re-do re-accept.
}
}
@@ -882,7 +882,7 @@ void CWalletTx::RelayWalletTransaction()
{
if (GetDepthInMainChain() == 0) {
uint256 hash = GetHash();
- printf("Relaying wtx %s\n", hash.ToString().c_str());
+ LogPrintf("Relaying wtx %s\n", hash.ToString().c_str());
RelayTransaction((CTransaction)*this, hash);
}
}
@@ -905,7 +905,7 @@ void CWallet::ResendWalletTransactions()
nLastResend = GetTime();
// Rebroadcast any of our txes that aren't in a block yet
- printf("ResendWalletTransactions()\n");
+ LogPrintf("ResendWalletTransactions()\n");
{
LOCK(cs_wallet);
// Sort them in chronological order
@@ -1145,12 +1145,11 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe
nValueRet += vValue[i].first;
}
- //// debug print
- printf("SelectCoins() best subset: ");
+ LogPrint("selectcoins", "SelectCoins() best subset: ");
for (unsigned int i = 0; i < vValue.size(); i++)
if (vfBest[i])
- printf("%s ", FormatMoney(vValue[i].first).c_str());
- printf("total %s\n", FormatMoney(nBest).c_str());
+ LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first).c_str());
+ LogPrint("selectcoins", "total %s\n", FormatMoney(nBest).c_str());
}
return true;
@@ -1232,9 +1231,10 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend,
}
int64 nChange = nValueIn - nValue - nFeeRet;
- // if sub-cent change is required, the fee must be raised to at least nMinTxFee
- // or until nChange becomes zero
- // NOTE: this depends on the exact behaviour of GetMinFee
+ // The following if statement should be removed once enough miners
+ // have upgraded to the 0.9 GetMinFee() rules. Until then, this avoids
+ // creating free transactions that have change outputs less than
+ // CENT bitcoins.
if (nFeeRet < CTransaction::nMinTxFee && nChange > 0 && nChange < CENT)
{
int64 nMoveToFee = min(nChange, CTransaction::nMinTxFee - nFeeRet);
@@ -1336,7 +1336,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
{
{
LOCK2(cs_main, cs_wallet);
- printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
+ LogPrintf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
{
// This is only to keep the database open to defeat the auto-flush for the
// duration of this scope. This is the only place where this optimization
@@ -1372,7 +1372,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
if (!wtxNew.AcceptToMemoryPool(false))
{
// This must not fail. The transaction has already been signed and recorded.
- printf("CommitTransaction() : Error: Transaction not valid");
+ LogPrintf("CommitTransaction() : Error: Transaction not valid");
return false;
}
wtxNew.RelayWalletTransaction();
@@ -1391,7 +1391,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
if (IsLocked())
{
string strError = _("Error: Wallet locked, unable to create transaction!");
- printf("SendMoney() : %s", strError.c_str());
+ LogPrintf("SendMoney() : %s", strError.c_str());
return strError;
}
string strError;
@@ -1399,7 +1399,7 @@ string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew,
{
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());
+ LogPrintf("SendMoney() : %s\n", strError.c_str());
return strError;
}
@@ -1457,26 +1457,32 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
}
-bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
+bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
{
- std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
- mapAddressBook[address] = strName;
- NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
+ std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
+ mapAddressBook[address].name = strName;
+ if (!strPurpose.empty()) /* update purpose only if requested */
+ mapAddressBook[address].purpose = strPurpose;
+ NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
+ mapAddressBook[address].purpose,
+ (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
if (!fFileBacked)
return false;
+ if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
+ return false;
return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
}
-bool CWallet::DelAddressBookName(const CTxDestination& address)
+bool CWallet::DelAddressBook(const CTxDestination& address)
{
mapAddressBook.erase(address);
- NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
+ NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
if (!fFileBacked)
return false;
+ CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
}
-
void CWallet::PrintWallet(const CBlock& block)
{
{
@@ -1484,10 +1490,10 @@ void CWallet::PrintWallet(const CBlock& block)
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());
+ LogPrintf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
}
}
- printf("\n");
+ LogPrintf("\n");
}
bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
@@ -1546,12 +1552,12 @@ bool CWallet::NewKeyPool()
walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
setKeyPool.insert(nIndex);
}
- printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
+ LogPrintf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
}
return true;
}
-bool CWallet::TopUpKeyPool()
+bool CWallet::TopUpKeyPool(unsigned int kpSize)
{
{
LOCK(cs_wallet);
@@ -1562,7 +1568,12 @@ bool CWallet::TopUpKeyPool()
CWalletDB walletdb(strWalletFile);
// Top up key pool
- unsigned int nTargetSize = max(GetArg("-keypool", 100), 0LL);
+ unsigned int nTargetSize;
+ if (kpSize > 0)
+ nTargetSize = kpSize;
+ else
+ nTargetSize = max(GetArg("-keypool", 100), 0LL);
+
while (setKeyPool.size() < (nTargetSize + 1))
{
int64 nEnd = 1;
@@ -1571,7 +1582,7 @@ bool CWallet::TopUpKeyPool()
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());
+ LogPrintf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size());
}
}
return true;
@@ -1600,7 +1611,7 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
if (!HaveKey(keypool.vchPubKey.GetID()))
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
assert(keypool.vchPubKey.IsValid());
- printf("keypool reserve %"PRI64d"\n", nIndex);
+ LogPrintf("keypool reserve %"PRI64d"\n", nIndex);
}
}
@@ -1627,7 +1638,7 @@ void CWallet::KeepKey(int64 nIndex)
CWalletDB walletdb(strWalletFile);
walletdb.ErasePool(nIndex);
}
- printf("keypool keep %"PRI64d"\n", nIndex);
+ LogPrintf("keypool keep %"PRI64d"\n", nIndex);
}
void CWallet::ReturnKey(int64 nIndex)
@@ -1637,10 +1648,10 @@ void CWallet::ReturnKey(int64 nIndex)
LOCK(cs_wallet);
setKeyPool.insert(nIndex);
}
- printf("keypool return %"PRI64d"\n", nIndex);
+ LogPrintf("keypool return %"PRI64d"\n", nIndex);
}
-bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
+bool CWallet::GetKeyFromPool(CPubKey& result)
{
int64 nIndex = 0;
CKeyPool keypool;
@@ -1649,11 +1660,6 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
ReserveKeyFromKeyPool(nIndex, keypool);
if (nIndex == -1)
{
- if (fAllowReuse && vchDefaultKey.IsValid())
- {
- result = vchDefaultKey;
- return true;
- }
if (IsLocked()) return false;
result = GenerateNewKey();
return true;
@@ -1807,6 +1813,19 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
return ret;
}
+set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
+{
+ set<CTxDestination> result;
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
+ {
+ const CTxDestination& address = item.first;
+ const string& strName = item.second.name;
+ if (strName == strAccount)
+ result.insert(address);
+ }
+ return result;
+}
+
bool CReserveKey::GetReservedKey(CPubKey& pubkey)
{
if (nIndex == -1)
@@ -1817,7 +1836,7 @@ bool CReserveKey::GetReservedKey(CPubKey& pubkey)
vchPubKey = keypool.vchPubKey;
else {
if (pwallet->vchDefaultKey.IsValid()) {
- printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
+ LogPrintf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
vchPubKey = pwallet->vchDefaultKey;
} else
return false;
@@ -1915,7 +1934,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64> &mapKeyBirth) const {
mapKeyBirth[it->first] = it->second.nCreateTime;
// map in which we'll infer heights of other keys
- CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin
+ CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
std::set<CKeyID> setKeys;
GetKeys(setKeys);
@@ -1935,7 +1954,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64> &mapKeyBirth) const {
// iterate over all wallet transactions...
const CWalletTx &wtx = (*it).second;
std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
- if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) {
+ if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
// ... which are already in a block
int nHeight = blit->second->nHeight;
BOOST_FOREACH(const CTxOut &txout, wtx.vout) {