]> Git Repo - VerusCoin.git/blame - src/wallet.cpp
Remove -beta suffix
[VerusCoin.git] / src / wallet.cpp
CommitLineData
b2120e22 1// Copyright (c) 2009-2010 Satoshi Nakamoto
57702541 2// Copyright (c) 2009-2014 The Bitcoin developers
e8ef3da7 3// Distributed under the MIT/X11 software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
e8ef3da7 5
9eace6b1 6#include "wallet.h"
51ed9ec9 7
10254401 8#include "base58.h"
3e1cf9b6 9#include "checkpoints.h"
6a86c24d 10#include "coincontrol.h"
0689f46c 11#include "net.h"
51ed9ec9 12
cae686d3 13#include <boost/algorithm/string/replace.hpp>
51ed9ec9 14#include <openssl/rand.h>
e8ef3da7
WL
15
16using namespace std;
17
cd7fa8bb 18// Settings
c6cb21d1 19CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
1bbca249 20bool bSpendZeroConfChange = true;
e8ef3da7 21
e8ef3da7
WL
22//////////////////////////////////////////////////////////////////////////////
23//
24// mapWallet
25//
26
d650f96d
CM
27struct CompareValueOnly
28{
51ed9ec9
BD
29 bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1,
30 const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t2) const
d650f96d
CM
31 {
32 return t1.first < t2.first;
33 }
34};
35
93a18a36
GA
36const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
37{
38 LOCK(cs_wallet);
39 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
40 if (it == mapWallet.end())
41 return NULL;
42 return &(it->second);
43}
44
fd61d6f5 45CPubKey CWallet::GenerateNewKey()
9976cf07 46{
95691680 47 AssertLockHeld(cs_wallet); // mapKeyMetadata
439e1497 48 bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
38067c18 49
9976cf07 50 RandAddSeedPerfmon();
dfa23b94
PW
51 CKey secret;
52 secret.MakeNewKey(fCompressed);
38067c18
PW
53
54 // Compressed public keys were introduced in version 0.6.0
55 if (fCompressed)
439e1497 56 SetMinVersion(FEATURE_COMPRPUBKEY);
38067c18 57
dfa23b94 58 CPubKey pubkey = secret.GetPubKey();
4addb2c0
PW
59
60 // Create new metadata
51ed9ec9 61 int64_t nCreationTime = GetTime();
4addb2c0
PW
62 mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
63 if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
64 nTimeFirstKey = nCreationTime;
65
dfa23b94 66 if (!AddKeyPubKey(secret, pubkey))
9976cf07 67 throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
dfa23b94 68 return pubkey;
9976cf07 69}
e8ef3da7 70
4addb2c0 71bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
e8ef3da7 72{
95691680 73 AssertLockHeld(cs_wallet); // mapKeyMetadata
dfa23b94 74 if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
acd65016 75 return false;
e8ef3da7
WL
76 if (!fFileBacked)
77 return true;
dfa23b94 78 if (!IsCrypted()) {
3869fb89
JG
79 return CWalletDB(strWalletFile).WriteKey(pubkey,
80 secret.GetPrivKey(),
4addb2c0 81 mapKeyMetadata[pubkey.GetID()]);
dfa23b94 82 }
84c3c2eb 83 return true;
4e87d341
MC
84}
85
3869fb89 86bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
4addb2c0 87 const vector<unsigned char> &vchCryptedSecret)
4e87d341
MC
88{
89 if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
90 return false;
91 if (!fFileBacked)
92 return true;
96f34cd5 93 {
f8dcd5ca 94 LOCK(cs_wallet);
96f34cd5 95 if (pwalletdbEncryption)
3869fb89
JG
96 return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
97 vchCryptedSecret,
4addb2c0 98 mapKeyMetadata[vchPubKey.GetID()]);
96f34cd5 99 else
3869fb89
JG
100 return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
101 vchCryptedSecret,
4addb2c0 102 mapKeyMetadata[vchPubKey.GetID()]);
96f34cd5 103 }
0767e691 104 return false;
4e87d341
MC
105}
106
4addb2c0
PW
107bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
108{
95691680 109 AssertLockHeld(cs_wallet); // mapKeyMetadata
4addb2c0
PW
110 if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
111 nTimeFirstKey = meta.nCreateTime;
112
113 mapKeyMetadata[pubkey.GetID()] = meta;
114 return true;
115}
116
2f15e86a
GA
117bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
118{
119 return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
120}
121
922e8e29 122bool CWallet::AddCScript(const CScript& redeemScript)
e679ec96 123{
922e8e29 124 if (!CCryptoKeyStore::AddCScript(redeemScript))
e679ec96
GA
125 return false;
126 if (!fFileBacked)
127 return true;
922e8e29 128 return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
e679ec96
GA
129}
130
94f778bd 131bool CWallet::Unlock(const SecureString& strWalletPassphrase)
4e87d341 132{
6cc4a62c
GA
133 CCrypter crypter;
134 CKeyingMaterial vMasterKey;
4e87d341 135
f8dcd5ca
PW
136 {
137 LOCK(cs_wallet);
4e87d341
MC
138 BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
139 {
140 if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
141 return false;
142 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
92f2c1fe 143 continue; // try another master key
4e87d341
MC
144 if (CCryptoKeyStore::Unlock(vMasterKey))
145 return true;
146 }
f8dcd5ca 147 }
4e87d341
MC
148 return false;
149}
150
94f778bd 151bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
4e87d341 152{
6cc4a62c 153 bool fWasLocked = IsLocked();
4e87d341 154
6cc4a62c 155 {
f8dcd5ca 156 LOCK(cs_wallet);
4e87d341
MC
157 Lock();
158
159 CCrypter crypter;
160 CKeyingMaterial vMasterKey;
161 BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
162 {
163 if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
164 return false;
6cc4a62c 165 if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
4e87d341
MC
166 return false;
167 if (CCryptoKeyStore::Unlock(vMasterKey))
168 {
51ed9ec9 169 int64_t nStartTime = GetTimeMillis();
ddebdd9a
MC
170 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
171 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
172
173 nStartTime = GetTimeMillis();
174 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
175 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
176
177 if (pMasterKey.second.nDeriveIterations < 25000)
178 pMasterKey.second.nDeriveIterations = 25000;
179
881a85a2 180 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
ddebdd9a 181
4e87d341
MC
182 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
183 return false;
184 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
185 return false;
186 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
187 if (fWasLocked)
188 Lock();
189 return true;
190 }
191 }
192 }
6cc4a62c 193
4e87d341
MC
194 return false;
195}
196
ed6d0b5f
PW
197void CWallet::SetBestChain(const CBlockLocator& loc)
198{
199 CWalletDB walletdb(strWalletFile);
200 walletdb.WriteBestBlock(loc);
201}
7414733b 202
439e1497 203bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
0b807a41 204{
ca4cf5cf 205 LOCK(cs_wallet); // nWalletVersion
0b807a41
PW
206 if (nWalletVersion >= nVersion)
207 return true;
208
439e1497
PW
209 // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
210 if (fExplicit && nVersion > nWalletMaxVersion)
211 nVersion = FEATURE_LATEST;
212
0b807a41
PW
213 nWalletVersion = nVersion;
214
439e1497
PW
215 if (nVersion > nWalletMaxVersion)
216 nWalletMaxVersion = nVersion;
217
0b807a41
PW
218 if (fFileBacked)
219 {
220 CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
0b807a41
PW
221 if (nWalletVersion > 40000)
222 pwalletdb->WriteMinVersion(nWalletVersion);
223 if (!pwalletdbIn)
224 delete pwalletdb;
225 }
226
227 return true;
228}
229
439e1497
PW
230bool CWallet::SetMaxVersion(int nVersion)
231{
ca4cf5cf 232 LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
439e1497
PW
233 // cannot downgrade below current version
234 if (nWalletVersion > nVersion)
235 return false;
236
237 nWalletMaxVersion = nVersion;
238
239 return true;
240}
241
731b89b8
GA
242set<uint256> CWallet::GetConflicts(const uint256& txid) const
243{
244 set<uint256> result;
245 AssertLockHeld(cs_wallet);
246
247 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
248 if (it == mapWallet.end())
249 return result;
250 const CWalletTx& wtx = it->second;
251
93a18a36 252 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
731b89b8
GA
253
254 BOOST_FOREACH(const CTxIn& txin, wtx.vin)
255 {
93a18a36
GA
256 if (mapTxSpends.count(txin.prevout) <= 1)
257 continue; // No conflict if zero or one spends
258 range = mapTxSpends.equal_range(txin.prevout);
259 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
731b89b8
GA
260 result.insert(it->second);
261 }
262 return result;
263}
264
93a18a36 265void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
731b89b8
GA
266{
267 // We want all the wallet transactions in range to have the same metadata as
268 // the oldest (smallest nOrderPos).
269 // So: find smallest nOrderPos:
270
271 int nMinOrderPos = std::numeric_limits<int>::max();
272 const CWalletTx* copyFrom = NULL;
93a18a36 273 for (TxSpends::iterator it = range.first; it != range.second; ++it)
731b89b8
GA
274 {
275 const uint256& hash = it->second;
276 int n = mapWallet[hash].nOrderPos;
277 if (n < nMinOrderPos)
278 {
279 nMinOrderPos = n;
280 copyFrom = &mapWallet[hash];
281 }
282 }
283 // Now copy data from copyFrom to rest:
93a18a36 284 for (TxSpends::iterator it = range.first; it != range.second; ++it)
731b89b8
GA
285 {
286 const uint256& hash = it->second;
287 CWalletTx* copyTo = &mapWallet[hash];
288 if (copyFrom == copyTo) continue;
289 copyTo->mapValue = copyFrom->mapValue;
290 copyTo->vOrderForm = copyFrom->vOrderForm;
291 // fTimeReceivedIsTxTime not copied on purpose
292 // nTimeReceived not copied on purpose
293 copyTo->nTimeSmart = copyFrom->nTimeSmart;
294 copyTo->fFromMe = copyFrom->fFromMe;
295 copyTo->strFromAccount = copyFrom->strFromAccount;
731b89b8
GA
296 // nOrderPos not copied on purpose
297 // cached members not copied on purpose
298 }
299}
300
93a18a36
GA
301// Outpoint is spent if any non-conflicted transaction
302// spends it:
303bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
731b89b8 304{
93a18a36
GA
305 const COutPoint outpoint(hash, n);
306 pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
307 range = mapTxSpends.equal_range(outpoint);
731b89b8 308
93a18a36 309 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
731b89b8 310 {
93a18a36
GA
311 const uint256& wtxid = it->second;
312 std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
313 if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
314 return true; // Spent
731b89b8 315 }
93a18a36
GA
316 return false;
317}
318
319void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
320{
321 mapTxSpends.insert(make_pair(outpoint, wtxid));
322
323 pair<TxSpends::iterator, TxSpends::iterator> range;
324 range = mapTxSpends.equal_range(outpoint);
325 SyncMetaData(range);
326}
327
328
329void CWallet::AddToSpends(const uint256& wtxid)
330{
331 assert(mapWallet.count(wtxid));
332 CWalletTx& thisTx = mapWallet[wtxid];
333 if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
334 return;
335
336 BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
337 AddToSpends(txin.prevout, wtxid);
731b89b8
GA
338}
339
94f778bd 340bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
4e87d341 341{
6cc4a62c
GA
342 if (IsCrypted())
343 return false;
4e87d341 344
6cc4a62c
GA
345 CKeyingMaterial vMasterKey;
346 RandAddSeedPerfmon();
4e87d341 347
6cc4a62c
GA
348 vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
349 RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
4e87d341 350
6cc4a62c 351 CMasterKey kMasterKey;
4e87d341 352
6cc4a62c
GA
353 RandAddSeedPerfmon();
354 kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
355 RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
4e87d341 356
6cc4a62c 357 CCrypter crypter;
51ed9ec9 358 int64_t nStartTime = GetTimeMillis();
6cc4a62c
GA
359 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
360 kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
ddebdd9a 361
6cc4a62c
GA
362 nStartTime = GetTimeMillis();
363 crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
364 kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
ddebdd9a 365
6cc4a62c
GA
366 if (kMasterKey.nDeriveIterations < 25000)
367 kMasterKey.nDeriveIterations = 25000;
ddebdd9a 368
881a85a2 369 LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
ddebdd9a 370
6cc4a62c
GA
371 if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
372 return false;
373 if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
374 return false;
4e87d341 375
6cc4a62c 376 {
f8dcd5ca 377 LOCK(cs_wallet);
4e87d341
MC
378 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
379 if (fFileBacked)
380 {
96f34cd5 381 pwalletdbEncryption = new CWalletDB(strWalletFile);
0fb78eae
JG
382 if (!pwalletdbEncryption->TxnBegin())
383 return false;
96f34cd5 384 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
4e87d341
MC
385 }
386
387 if (!EncryptKeys(vMasterKey))
96f34cd5
MC
388 {
389 if (fFileBacked)
390 pwalletdbEncryption->TxnAbort();
391 exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
392 }
393
0b807a41 394 // Encryption was introduced in version 0.4.0
439e1497 395 SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
0b807a41 396
96f34cd5
MC
397 if (fFileBacked)
398 {
399 if (!pwalletdbEncryption->TxnCommit())
400 exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
401
fcfd7ff8 402 delete pwalletdbEncryption;
96f34cd5
MC
403 pwalletdbEncryption = NULL;
404 }
4e87d341 405
37971fcc
GA
406 Lock();
407 Unlock(strWalletPassphrase);
408 NewKeyPool();
4e87d341 409 Lock();
6cc4a62c 410
d764d916
GA
411 // Need to completely rewrite the wallet file; if we don't, bdb might keep
412 // bits of the unencrypted private key in slack space in the database file.
b2d3b2d6 413 CDB::Rewrite(strWalletFile);
fe4a6550 414
d764d916 415 }
ab1b288f 416 NotifyStatusChanged(this);
9e9869d0 417
4e87d341 418 return true;
e8ef3da7
WL
419}
420
51ed9ec9 421int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
da7b8c12 422{
95691680 423 AssertLockHeld(cs_wallet); // nOrderPosNext
51ed9ec9 424 int64_t nRet = nOrderPosNext++;
4291e8fe
PW
425 if (pwalletdb) {
426 pwalletdb->WriteOrderPosNext(nOrderPosNext);
427 } else {
428 CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
429 }
da7b8c12
LD
430 return nRet;
431}
432
ddb709e9 433CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
c3f95ef1 434{
95691680 435 AssertLockHeld(cs_wallet); // mapWallet
c3f95ef1
LD
436 CWalletDB walletdb(strWalletFile);
437
438 // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
439 TxItems txOrdered;
440
441 // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
442 // would make this much faster for applications that do this a lot.
443 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
444 {
445 CWalletTx* wtx = &((*it).second);
446 txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
447 }
ddb709e9 448 acentries.clear();
c3f95ef1
LD
449 walletdb.ListAccountCreditDebit(strAccount, acentries);
450 BOOST_FOREACH(CAccountingEntry& entry, acentries)
451 {
452 txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
453 }
454
455 return txOrdered;
456}
457
95d888a6
PW
458void CWallet::MarkDirty()
459{
95d888a6 460 {
f8dcd5ca 461 LOCK(cs_wallet);
95d888a6
PW
462 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
463 item.second.MarkDirty();
464 }
465}
466
731b89b8 467bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
e8ef3da7
WL
468{
469 uint256 hash = wtxIn.GetHash();
731b89b8
GA
470
471 if (fFromLoadWallet)
472 {
473 mapWallet[hash] = wtxIn;
09ec3af1 474 mapWallet[hash].BindWallet(this);
93a18a36 475 AddToSpends(hash);
731b89b8
GA
476 }
477 else
e8ef3da7 478 {
f8dcd5ca 479 LOCK(cs_wallet);
e8ef3da7
WL
480 // Inserts only if not already there, returns tx inserted or tx found
481 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
482 CWalletTx& wtx = (*ret.first).second;
4c6e2295 483 wtx.BindWallet(this);
e8ef3da7
WL
484 bool fInsertedNew = ret.second;
485 if (fInsertedNew)
9c7722b7 486 {
e8ef3da7 487 wtx.nTimeReceived = GetAdjustedTime();
da7b8c12 488 wtx.nOrderPos = IncOrderPosNext();
c3f95ef1
LD
489
490 wtx.nTimeSmart = wtx.nTimeReceived;
491 if (wtxIn.hashBlock != 0)
492 {
493 if (mapBlockIndex.count(wtxIn.hashBlock))
494 {
495 unsigned int latestNow = wtx.nTimeReceived;
496 unsigned int latestEntry = 0;
497 {
498 // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
51ed9ec9 499 int64_t latestTolerated = latestNow + 300;
ddb709e9
LD
500 std::list<CAccountingEntry> acentries;
501 TxItems txOrdered = OrderedTxItems(acentries);
c3f95ef1
LD
502 for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
503 {
504 CWalletTx *const pwtx = (*it).second.first;
505 if (pwtx == &wtx)
506 continue;
507 CAccountingEntry *const pacentry = (*it).second.second;
51ed9ec9 508 int64_t nSmartTime;
c3f95ef1
LD
509 if (pwtx)
510 {
511 nSmartTime = pwtx->nTimeSmart;
512 if (!nSmartTime)
513 nSmartTime = pwtx->nTimeReceived;
514 }
515 else
516 nSmartTime = pacentry->nTime;
517 if (nSmartTime <= latestTolerated)
518 {
519 latestEntry = nSmartTime;
520 if (nSmartTime > latestNow)
521 latestNow = nSmartTime;
522 break;
523 }
524 }
525 }
526
527 unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
528 wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
529 }
530 else
881a85a2 531 LogPrintf("AddToWallet() : found %s in block %s not in index\n",
7d9d134b
WL
532 wtxIn.GetHash().ToString(),
533 wtxIn.hashBlock.ToString());
c3f95ef1 534 }
93a18a36 535 AddToSpends(hash);
9c7722b7 536 }
e8ef3da7
WL
537
538 bool fUpdated = false;
539 if (!fInsertedNew)
540 {
541 // Merge
542 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
543 {
544 wtx.hashBlock = wtxIn.hashBlock;
545 fUpdated = true;
546 }
547 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
548 {
549 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
550 wtx.nIndex = wtxIn.nIndex;
551 fUpdated = true;
552 }
553 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
554 {
555 wtx.fFromMe = wtxIn.fFromMe;
556 fUpdated = true;
557 }
e8ef3da7
WL
558 }
559
560 //// debug print
7d9d134b 561 LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
e8ef3da7
WL
562
563 // Write to disk
564 if (fInsertedNew || fUpdated)
565 if (!wtx.WriteToDisk())
566 return false;
ee4b170c 567
93a18a36
GA
568 // Break debit/credit balance caches:
569 wtx.MarkDirty();
e8ef3da7 570
fe4a6550
WL
571 // Notify UI of new or updated transaction
572 NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
cae686d3 573
574 // notify an external script when a wallet transaction comes in or is updated
575 std::string strCmd = GetArg("-walletnotify", "");
576
577 if ( !strCmd.empty())
578 {
579 boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
580 boost::thread t(runCommand, strCmd); // thread runs free
581 }
582
fe4a6550 583 }
e8ef3da7
WL
584 return true;
585}
586
d825e6a3
PW
587// Add a transaction to the wallet, or update it.
588// pblock is optional, but should be provided if the transaction is known to be in a block.
589// If fUpdate is true, existing transactions will be updated.
00588c3f 590bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate)
e8ef3da7 591{
e8ef3da7 592 {
53d56881 593 AssertLockHeld(cs_wallet);
6cc4a62c
GA
594 bool fExisted = mapWallet.count(hash);
595 if (fExisted && !fUpdate) return false;
596 if (fExisted || IsMine(tx) || IsFromMe(tx))
597 {
598 CWalletTx wtx(this,tx);
599 // Get merkle branch if transaction was found in a block
600 if (pblock)
601 wtx.SetMerkleBranch(pblock);
602 return AddToWallet(wtx);
603 }
e8ef3da7 604 }
e8ef3da7
WL
605 return false;
606}
607
93a18a36
GA
608void CWallet::SyncTransaction(const uint256 &hash, const CTransaction& tx, const CBlock* pblock)
609{
55a1db4f 610 LOCK2(cs_main, cs_wallet);
53d56881 611 if (!AddToWalletIfInvolvingMe(hash, tx, pblock, true))
93a18a36
GA
612 return; // Not one of ours
613
614 // If a transaction changes 'conflicted' state, that changes the balance
615 // available of the outputs it spends. So force those to be
616 // recomputed, also:
617 BOOST_FOREACH(const CTxIn& txin, tx.vin)
618 {
619 if (mapWallet.count(txin.prevout.hash))
620 mapWallet[txin.prevout.hash].MarkDirty();
621 }
00588c3f
PW
622}
623
624void CWallet::EraseFromWallet(const uint256 &hash)
e8ef3da7
WL
625{
626 if (!fFileBacked)
00588c3f 627 return;
e8ef3da7 628 {
f8dcd5ca 629 LOCK(cs_wallet);
e8ef3da7
WL
630 if (mapWallet.erase(hash))
631 CWalletDB(strWalletFile).EraseTx(hash);
632 }
00588c3f 633 return;
e8ef3da7
WL
634}
635
636
637bool CWallet::IsMine(const CTxIn &txin) const
638{
e8ef3da7 639 {
f8dcd5ca 640 LOCK(cs_wallet);
e8ef3da7
WL
641 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
642 if (mi != mapWallet.end())
643 {
644 const CWalletTx& prev = (*mi).second;
645 if (txin.prevout.n < prev.vout.size())
646 if (IsMine(prev.vout[txin.prevout.n]))
647 return true;
648 }
649 }
650 return false;
651}
652
51ed9ec9 653int64_t CWallet::GetDebit(const CTxIn &txin) const
e8ef3da7 654{
e8ef3da7 655 {
f8dcd5ca 656 LOCK(cs_wallet);
e8ef3da7
WL
657 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
658 if (mi != mapWallet.end())
659 {
660 const CWalletTx& prev = (*mi).second;
661 if (txin.prevout.n < prev.vout.size())
662 if (IsMine(prev.vout[txin.prevout.n]))
663 return prev.vout[txin.prevout.n].nValue;
664 }
665 }
666 return 0;
667}
668
e679ec96
GA
669bool CWallet::IsChange(const CTxOut& txout) const
670{
10254401 671 CTxDestination address;
2a45a494
GA
672
673 // TODO: fix handling of 'change' outputs. The assumption is that any
674 // payment to a TX_PUBKEYHASH that is mine but isn't in the address book
675 // is change. That assumption is likely to break when we implement multisignature
676 // wallets that return change back into a multi-signature-protected address;
677 // a better way of identifying which outputs are 'the send' and which are
678 // 'the change' will need to be implemented (maybe extend CWalletTx to remember
679 // which output, if any, was change).
10254401 680 if (ExtractDestination(txout.scriptPubKey, address) && ::IsMine(*this, address))
f8dcd5ca
PW
681 {
682 LOCK(cs_wallet);
683 if (!mapAddressBook.count(address))
684 return true;
685 }
e679ec96
GA
686 return false;
687}
688
51ed9ec9 689int64_t CWalletTx::GetTxTime() const
e8ef3da7 690{
51ed9ec9 691 int64_t n = nTimeSmart;
c3f95ef1 692 return n ? n : nTimeReceived;
e8ef3da7
WL
693}
694
695int CWalletTx::GetRequestCount() const
696{
697 // Returns -1 if it wasn't being tracked
698 int nRequests = -1;
e8ef3da7 699 {
f8dcd5ca 700 LOCK(pwallet->cs_wallet);
e8ef3da7
WL
701 if (IsCoinBase())
702 {
703 // Generated block
704 if (hashBlock != 0)
705 {
706 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
707 if (mi != pwallet->mapRequestCount.end())
708 nRequests = (*mi).second;
709 }
710 }
711 else
712 {
713 // Did anyone request this transaction?
714 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
715 if (mi != pwallet->mapRequestCount.end())
716 {
717 nRequests = (*mi).second;
718
719 // How about the block it's in?
720 if (nRequests == 0 && hashBlock != 0)
721 {
722 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
723 if (mi != pwallet->mapRequestCount.end())
724 nRequests = (*mi).second;
725 else
726 nRequests = 1; // If it's in someone else's block it must have got out
727 }
728 }
729 }
730 }
731 return nRequests;
732}
733
51ed9ec9
BD
734void CWalletTx::GetAmounts(list<pair<CTxDestination, int64_t> >& listReceived,
735 list<pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, string& strSentAccount) const
e8ef3da7 736{
e07c8e91 737 nFee = 0;
e8ef3da7
WL
738 listReceived.clear();
739 listSent.clear();
740 strSentAccount = strFromAccount;
741
e8ef3da7 742 // Compute fee:
51ed9ec9 743 int64_t nDebit = GetDebit();
e8ef3da7
WL
744 if (nDebit > 0) // debit>0 means we signed/sent this transaction
745 {
0733c1bd 746 int64_t nValueOut = GetValueOut();
e8ef3da7
WL
747 nFee = nDebit - nValueOut;
748 }
749
e679ec96 750 // Sent/received.
e8ef3da7
WL
751 BOOST_FOREACH(const CTxOut& txout, vout)
752 {
96ed6821
LD
753 bool fIsMine;
754 // Only need to handle txouts if AT LEAST one of these is true:
755 // 1) they debit from us (sent)
756 // 2) the output is to us (received)
757 if (nDebit > 0)
758 {
759 // Don't report 'change' txouts
760 if (pwallet->IsChange(txout))
761 continue;
762 fIsMine = pwallet->IsMine(txout);
763 }
764 else if (!(fIsMine = pwallet->IsMine(txout)))
765 continue;
766
767 // In either case, we need to get the destination address
10254401 768 CTxDestination address;
10254401 769 if (!ExtractDestination(txout.scriptPubKey, address))
e8ef3da7 770 {
881a85a2 771 LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
7d9d134b 772 this->GetHash().ToString());
96ed6821 773 address = CNoDestination();
e8ef3da7
WL
774 }
775
96ed6821 776 // If we are debited by the transaction, add the output as a "sent" entry
e8ef3da7
WL
777 if (nDebit > 0)
778 listSent.push_back(make_pair(address, txout.nValue));
779
96ed6821
LD
780 // If we are receiving the output, add it as a "received" entry
781 if (fIsMine)
e8ef3da7
WL
782 listReceived.push_back(make_pair(address, txout.nValue));
783 }
784
785}
786
51ed9ec9
BD
787void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
788 int64_t& nSent, int64_t& nFee) const
e8ef3da7 789{
e07c8e91 790 nReceived = nSent = nFee = 0;
e8ef3da7 791
51ed9ec9 792 int64_t allFee;
e8ef3da7 793 string strSentAccount;
51ed9ec9
BD
794 list<pair<CTxDestination, int64_t> > listReceived;
795 list<pair<CTxDestination, int64_t> > listSent;
e07c8e91 796 GetAmounts(listReceived, listSent, allFee, strSentAccount);
e8ef3da7 797
e8ef3da7
WL
798 if (strAccount == strSentAccount)
799 {
51ed9ec9 800 BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& s, listSent)
e8ef3da7
WL
801 nSent += s.second;
802 nFee = allFee;
803 }
e8ef3da7 804 {
f8dcd5ca 805 LOCK(pwallet->cs_wallet);
51ed9ec9 806 BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
e8ef3da7
WL
807 {
808 if (pwallet->mapAddressBook.count(r.first))
809 {
61885513
GA
810 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
811 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
e8ef3da7
WL
812 nReceived += r.second;
813 }
814 else if (strAccount.empty())
815 {
816 nReceived += r.second;
817 }
818 }
819 }
820}
821
722fa283 822
e8ef3da7
WL
823bool CWalletTx::WriteToDisk()
824{
825 return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
826}
827
d825e6a3
PW
828// Scan the block chain (starting in pindexStart) for transactions
829// from or to us. If fUpdate is true, found transactions that already
830// exist in the wallet will be updated.
e8ef3da7
WL
831int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
832{
833 int ret = 0;
75b8953a 834 int64_t nNow = GetTime();
e8ef3da7
WL
835
836 CBlockIndex* pindex = pindexStart;
e8ef3da7 837 {
55a1db4f 838 LOCK2(cs_main, cs_wallet);
39278369
CL
839
840 // no need to read and scan block, if block was created before
841 // our wallet birthday (as adjusted for block time variability)
842 while (pindex && nTimeFirstKey && (pindex->nTime < (nTimeFirstKey - 7200)))
843 pindex = chainActive.Next(pindex);
844
845 ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
846 double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
847 double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
e8ef3da7
WL
848 while (pindex)
849 {
39278369
CL
850 if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
851 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
8da9dd07 852
e8ef3da7 853 CBlock block;
7db120d5 854 ReadBlockFromDisk(block, pindex);
e8ef3da7
WL
855 BOOST_FOREACH(CTransaction& tx, block.vtx)
856 {
64dd46fd 857 if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate))
e8ef3da7
WL
858 ret++;
859 }
4c6d41b8 860 pindex = chainActive.Next(pindex);
75b8953a
B
861 if (GetTime() >= nNow + 60) {
862 nNow = GetTime();
863 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex));
864 }
e8ef3da7 865 }
39278369 866 ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
e8ef3da7
WL
867 }
868 return ret;
869}
870
871void CWallet::ReacceptWalletTransactions()
872{
55a1db4f 873 LOCK2(cs_main, cs_wallet);
93a18a36 874 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
e8ef3da7 875 {
93a18a36
GA
876 const uint256& wtxid = item.first;
877 CWalletTx& wtx = item.second;
878 assert(wtx.GetHash() == wtxid);
e8ef3da7 879
93a18a36
GA
880 int nDepth = wtx.GetDepthInMainChain();
881
882 if (!wtx.IsCoinBase() && nDepth < 0)
e8ef3da7 883 {
93a18a36
GA
884 // Try to add to memory pool
885 LOCK(mempool.cs);
886 wtx.AcceptToMemoryPool(false);
e8ef3da7
WL
887 }
888 }
889}
890
ae8bfd12 891void CWalletTx::RelayWalletTransaction()
e8ef3da7 892{
e8ef3da7
WL
893 if (!IsCoinBase())
894 {
5eaf91a4
PW
895 if (GetDepthInMainChain() == 0) {
896 uint256 hash = GetHash();
7d9d134b 897 LogPrintf("Relaying wtx %s\n", hash.ToString());
269d9c64 898 RelayTransaction((CTransaction)*this, hash);
e8ef3da7
WL
899 }
900 }
901}
902
731b89b8
GA
903set<uint256> CWalletTx::GetConflicts() const
904{
905 set<uint256> result;
906 if (pwallet != NULL)
907 {
908 uint256 myHash = GetHash();
909 result = pwallet->GetConflicts(myHash);
910 result.erase(myHash);
911 }
912 return result;
913}
914
e8ef3da7
WL
915void CWallet::ResendWalletTransactions()
916{
917 // Do this infrequently and randomly to avoid giving away
918 // that these are our transactions.
203d1ae6 919 if (GetTime() < nNextResend)
e8ef3da7 920 return;
203d1ae6
LD
921 bool fFirst = (nNextResend == 0);
922 nNextResend = GetTime() + GetRand(30 * 60);
e8ef3da7
WL
923 if (fFirst)
924 return;
925
926 // Only do it if there's been a new block since last time
203d1ae6 927 if (nTimeBestReceived < nLastResend)
e8ef3da7 928 return;
203d1ae6 929 nLastResend = GetTime();
e8ef3da7
WL
930
931 // Rebroadcast any of our txes that aren't in a block yet
881a85a2 932 LogPrintf("ResendWalletTransactions()\n");
e8ef3da7 933 {
f8dcd5ca 934 LOCK(cs_wallet);
e8ef3da7
WL
935 // Sort them in chronological order
936 multimap<unsigned int, CWalletTx*> mapSorted;
937 BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
938 {
939 CWalletTx& wtx = item.second;
940 // Don't rebroadcast until it's had plenty of time that
941 // it should have gotten in already by now.
51ed9ec9 942 if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60)
e8ef3da7
WL
943 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
944 }
945 BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
946 {
947 CWalletTx& wtx = *item.second;
ae8bfd12 948 wtx.RelayWalletTransaction();
e8ef3da7
WL
949 }
950 }
951}
952
953
954
955
956
957
958//////////////////////////////////////////////////////////////////////////////
959//
960// Actions
961//
962
963
51ed9ec9 964int64_t CWallet::GetBalance() const
e8ef3da7 965{
51ed9ec9 966 int64_t nTotal = 0;
e8ef3da7 967 {
55a1db4f 968 LOCK2(cs_main, cs_wallet);
e8ef3da7
WL
969 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
970 {
971 const CWalletTx* pcoin = &(*it).second;
0542619d 972 if (pcoin->IsTrusted())
8fdb7e10 973 nTotal += pcoin->GetAvailableCredit();
e8ef3da7
WL
974 }
975 }
976
e8ef3da7
WL
977 return nTotal;
978}
979
51ed9ec9 980int64_t CWallet::GetUnconfirmedBalance() const
df5ccbd2 981{
51ed9ec9 982 int64_t nTotal = 0;
df5ccbd2 983 {
55a1db4f 984 LOCK2(cs_main, cs_wallet);
df5ccbd2
WL
985 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
986 {
987 const CWalletTx* pcoin = &(*it).second;
731b89b8 988 if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
8fdb7e10 989 nTotal += pcoin->GetAvailableCredit();
990 }
991 }
992 return nTotal;
993}
994
51ed9ec9 995int64_t CWallet::GetImmatureBalance() const
8fdb7e10 996{
51ed9ec9 997 int64_t nTotal = 0;
8fdb7e10 998 {
55a1db4f 999 LOCK2(cs_main, cs_wallet);
8fdb7e10 1000 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1001 {
966a0e8c
PK
1002 const CWalletTx* pcoin = &(*it).second;
1003 nTotal += pcoin->GetImmatureCredit();
df5ccbd2
WL
1004 }
1005 }
1006 return nTotal;
1007}
e8ef3da7 1008
831f59ce 1009// populate vCoins with vector of spendable COutputs
6a86c24d 1010void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
9b0369c7
CM
1011{
1012 vCoins.clear();
1013
1014 {
1015 LOCK(cs_wallet);
1016 for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1017 {
93a18a36 1018 const uint256& wtxid = it->first;
9b0369c7
CM
1019 const CWalletTx* pcoin = &(*it).second;
1020
05df3fc6 1021 if (!IsFinalTx(*pcoin))
a2709fad
GA
1022 continue;
1023
0542619d 1024 if (fOnlyConfirmed && !pcoin->IsTrusted())
9b0369c7
CM
1025 continue;
1026
1027 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1028 continue;
1029
2b72d46f
GA
1030 int nDepth = pcoin->GetDepthInMainChain();
1031 if (nDepth < 0)
1032 continue;
1033
fdbb537d 1034 for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
93a18a36 1035 if (!(IsSpent(wtxid, i)) && IsMine(pcoin->vout[i]) &&
6a86c24d
CL
1036 !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 &&
1037 (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
2b72d46f 1038 vCoins.push_back(COutput(pcoin, i, nDepth));
fdbb537d 1039 }
9b0369c7
CM
1040 }
1041 }
1042}
1043
51ed9ec9
BD
1044static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > >vValue, int64_t nTotalLower, int64_t nTargetValue,
1045 vector<char>& vfBest, int64_t& nBest, int iterations = 1000)
831f59ce
CM
1046{
1047 vector<char> vfIncluded;
1048
1049 vfBest.assign(vValue.size(), true);
1050 nBest = nTotalLower;
1051
907a2aa4
GM
1052 seed_insecure_rand();
1053
831f59ce
CM
1054 for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1055 {
1056 vfIncluded.assign(vValue.size(), false);
51ed9ec9 1057 int64_t nTotal = 0;
831f59ce
CM
1058 bool fReachedTarget = false;
1059 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1060 {
1061 for (unsigned int i = 0; i < vValue.size(); i++)
1062 {
907a2aa4
GM
1063 //The solver here uses a randomized algorithm,
1064 //the randomness serves no real security purpose but is just
1065 //needed to prevent degenerate behavior and it is important
1066 //that the rng fast. We do not use a constant random sequence,
1067 //because there may be some privacy improvement by making
1068 //the selection random.
1069 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
831f59ce
CM
1070 {
1071 nTotal += vValue[i].first;
1072 vfIncluded[i] = true;
1073 if (nTotal >= nTargetValue)
1074 {
1075 fReachedTarget = true;
1076 if (nTotal < nBest)
1077 {
1078 nBest = nTotal;
1079 vfBest = vfIncluded;
1080 }
1081 nTotal -= vValue[i].first;
1082 vfIncluded[i] = false;
1083 }
1084 }
1085 }
1086 }
1087 }
1088}
1089
51ed9ec9
BD
1090bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
1091 set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const
e8ef3da7
WL
1092{
1093 setCoinsRet.clear();
1094 nValueRet = 0;
1095
1096 // List of values less than target
51ed9ec9
BD
1097 pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1098 coinLowestLarger.first = std::numeric_limits<int64_t>::max();
e8ef3da7 1099 coinLowestLarger.second.first = NULL;
51ed9ec9
BD
1100 vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue;
1101 int64_t nTotalLower = 0;
e8ef3da7 1102
e333ab56
CM
1103 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1104
9b0369c7 1105 BOOST_FOREACH(COutput output, vCoins)
e8ef3da7 1106 {
9b0369c7 1107 const CWalletTx *pcoin = output.tx;
e8ef3da7 1108
9b0369c7
CM
1109 if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
1110 continue;
e8ef3da7 1111
9b0369c7 1112 int i = output.i;
51ed9ec9 1113 int64_t n = pcoin->vout[i].nValue;
e8ef3da7 1114
51ed9ec9 1115 pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
e8ef3da7 1116
9b0369c7
CM
1117 if (n == nTargetValue)
1118 {
1119 setCoinsRet.insert(coin.second);
1120 nValueRet += coin.first;
1121 return true;
1122 }
1123 else if (n < nTargetValue + CENT)
1124 {
1125 vValue.push_back(coin);
1126 nTotalLower += n;
1127 }
1128 else if (n < coinLowestLarger.first)
1129 {
1130 coinLowestLarger = coin;
e8ef3da7
WL
1131 }
1132 }
1133
831f59ce 1134 if (nTotalLower == nTargetValue)
e8ef3da7 1135 {
c376ac35 1136 for (unsigned int i = 0; i < vValue.size(); ++i)
e8ef3da7
WL
1137 {
1138 setCoinsRet.insert(vValue[i].second);
1139 nValueRet += vValue[i].first;
1140 }
1141 return true;
1142 }
1143
831f59ce 1144 if (nTotalLower < nTargetValue)
e8ef3da7
WL
1145 {
1146 if (coinLowestLarger.second.first == NULL)
1147 return false;
1148 setCoinsRet.insert(coinLowestLarger.second);
1149 nValueRet += coinLowestLarger.first;
1150 return true;
1151 }
1152
e8ef3da7 1153 // Solve subset sum by stochastic approximation
d650f96d 1154 sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
831f59ce 1155 vector<char> vfBest;
51ed9ec9 1156 int64_t nBest;
e8ef3da7 1157
831f59ce
CM
1158 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1159 if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1160 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
e8ef3da7 1161
831f59ce
CM
1162 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1163 // or the next bigger coin is closer), return the bigger coin
1164 if (coinLowestLarger.second.first &&
1165 ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
e8ef3da7
WL
1166 {
1167 setCoinsRet.insert(coinLowestLarger.second);
1168 nValueRet += coinLowestLarger.first;
1169 }
1170 else {
c376ac35 1171 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7
WL
1172 if (vfBest[i])
1173 {
1174 setCoinsRet.insert(vValue[i].second);
1175 nValueRet += vValue[i].first;
1176 }
1177
faaeae1e 1178 LogPrint("selectcoins", "SelectCoins() best subset: ");
c376ac35 1179 for (unsigned int i = 0; i < vValue.size(); i++)
e8ef3da7 1180 if (vfBest[i])
7d9d134b
WL
1181 LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
1182 LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
e8ef3da7
WL
1183 }
1184
1185 return true;
1186}
1187
6a86c24d 1188bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const
e8ef3da7 1189{
9b0369c7 1190 vector<COutput> vCoins;
6a86c24d
CL
1191 AvailableCoins(vCoins, true, coinControl);
1192
1193 // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1194 if (coinControl && coinControl->HasSelected())
1195 {
1196 BOOST_FOREACH(const COutput& out, vCoins)
1197 {
1198 nValueRet += out.tx->vout[out.i].nValue;
1199 setCoinsRet.insert(make_pair(out.tx, out.i));
1200 }
1201 return (nValueRet >= nTargetValue);
1202 }
9b0369c7
CM
1203
1204 return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1205 SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1bbca249 1206 (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
e8ef3da7
WL
1207}
1208
1209
1210
1211
51ed9ec9 1212bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
6a86c24d 1213 CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
e8ef3da7 1214{
51ed9ec9
BD
1215 int64_t nValue = 0;
1216 BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
e8ef3da7
WL
1217 {
1218 if (nValue < 0)
1f00f4e9
GA
1219 {
1220 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 1221 return false;
1f00f4e9 1222 }
e8ef3da7
WL
1223 nValue += s.second;
1224 }
1225 if (vecSend.empty() || nValue < 0)
1f00f4e9
GA
1226 {
1227 strFailReason = _("Transaction amounts must be positive");
e8ef3da7 1228 return false;
1f00f4e9 1229 }
e8ef3da7 1230
4c6e2295 1231 wtxNew.BindWallet(this);
e8ef3da7 1232
e8ef3da7 1233 {
f8dcd5ca 1234 LOCK2(cs_main, cs_wallet);
e8ef3da7 1235 {
c6cb21d1 1236 nFeeRet = payTxFee.GetFeePerK();
050d2e95 1237 while (true)
e8ef3da7
WL
1238 {
1239 wtxNew.vin.clear();
1240 wtxNew.vout.clear();
1241 wtxNew.fFromMe = true;
1242
51ed9ec9 1243 int64_t nTotalValue = nValue + nFeeRet;
e8ef3da7
WL
1244 double dPriority = 0;
1245 // vouts to the payees
51ed9ec9 1246 BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
8de9bb53
GA
1247 {
1248 CTxOut txout(s.second, s.first);
c6cb21d1 1249 if (txout.IsDust(CTransaction::minRelayTxFee))
1f00f4e9
GA
1250 {
1251 strFailReason = _("Transaction amount too small");
8de9bb53 1252 return false;
1f00f4e9 1253 }
8de9bb53
GA
1254 wtxNew.vout.push_back(txout);
1255 }
e8ef3da7
WL
1256
1257 // Choose coins to use
1258 set<pair<const CWalletTx*,unsigned int> > setCoins;
51ed9ec9 1259 int64_t nValueIn = 0;
6a86c24d 1260 if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
1f00f4e9
GA
1261 {
1262 strFailReason = _("Insufficient funds");
e8ef3da7 1263 return false;
1f00f4e9 1264 }
e8ef3da7
WL
1265 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1266 {
51ed9ec9 1267 int64_t nCredit = pcoin.first->vout[pcoin.second].nValue;
d7836552
GM
1268 //The priority after the next block (depth+1) is used instead of the current,
1269 //reflecting an assumption the user would accept a bit more delay for
1270 //a chance at a free transaction.
1271 dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1);
e8ef3da7
WL
1272 }
1273
51ed9ec9 1274 int64_t nChange = nValueIn - nValue - nFeeRet;
a7dd11c6
PW
1275
1276 if (nChange > 0)
e8ef3da7 1277 {
bf798734
GA
1278 // Fill a vout to ourself
1279 // TODO: pass in scriptChange instead of reservekey so
1280 // change transaction isn't always pay-to-bitcoin-address
e8ef3da7 1281 CScript scriptChange;
6a86c24d
CL
1282
1283 // coin control: send change to custom address
1284 if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1285 scriptChange.SetDestination(coinControl->destChange);
1286
1287 // no coin control: send change to newly generated address
1288 else
1289 {
1290 // Note: We use a new key here to keep it from being obvious which side is the change.
1291 // The drawback is that by not reusing a previous key, the change may be lost if a
1292 // backup is restored, if the backup doesn't have the new private key for the change.
1293 // If we reused the old key, it would be possible to add code to look for and
1294 // rediscover unknown transactions that were written with keys of ours to recover
1295 // post-backup change.
1296
1297 // Reserve a new key pair from key pool
1298 CPubKey vchPubKey;
9b59e3bd
GM
1299 bool ret;
1300 ret = reservekey.GetReservedKey(vchPubKey);
1301 assert(ret); // should never fail, as we just unlocked
6a86c24d
CL
1302
1303 scriptChange.SetDestination(vchPubKey.GetID());
1304 }
e8ef3da7 1305
8de9bb53
GA
1306 CTxOut newTxOut(nChange, scriptChange);
1307
1308 // Never create dust outputs; if we would, just
1309 // add the dust to the fee.
c6cb21d1 1310 if (newTxOut.IsDust(CTransaction::minRelayTxFee))
8de9bb53
GA
1311 {
1312 nFeeRet += nChange;
1313 reservekey.ReturnKey();
1314 }
1315 else
1316 {
1317 // Insert change txn at random position:
1318 vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()+1);
1319 wtxNew.vout.insert(position, newTxOut);
1320 }
e8ef3da7
WL
1321 }
1322 else
1323 reservekey.ReturnKey();
1324
1325 // Fill vin
1326 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1327 wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1328
1329 // Sign
1330 int nIn = 0;
1331 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1332 if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1f00f4e9
GA
1333 {
1334 strFailReason = _("Signing transaction failed");
e8ef3da7 1335 return false;
1f00f4e9 1336 }
e8ef3da7
WL
1337
1338 // Limit size
6b6aaa16 1339 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
41e1a0d7 1340 if (nBytes >= MAX_STANDARD_TX_SIZE)
1f00f4e9
GA
1341 {
1342 strFailReason = _("Transaction too large");
e8ef3da7 1343 return false;
1f00f4e9 1344 }
4d707d51 1345 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
e8ef3da7
WL
1346
1347 // Check that enough fee is included
c6cb21d1 1348 int64_t nPayFee = payTxFee.GetFee(nBytes);
05df3fc6 1349 bool fAllowFree = AllowFree(dPriority);
8dfd8c62 1350 int64_t nMinFee = GetMinFee(wtxNew, nBytes, fAllowFree, GMF_SEND);
e8ef3da7
WL
1351 if (nFeeRet < max(nPayFee, nMinFee))
1352 {
1353 nFeeRet = max(nPayFee, nMinFee);
1354 continue;
1355 }
1356
e8ef3da7
WL
1357 wtxNew.fTimeReceivedIsTxTime = true;
1358
1359 break;
1360 }
1361 }
1362 }
1363 return true;
1364}
1365
51ed9ec9 1366bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue,
6a86c24d 1367 CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
e8ef3da7 1368{
51ed9ec9 1369 vector< pair<CScript, int64_t> > vecSend;
e8ef3da7 1370 vecSend.push_back(make_pair(scriptPubKey, nValue));
6a86c24d 1371 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl);
e8ef3da7
WL
1372}
1373
1374// Call after CreateTransaction unless you want to abort
1375bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
1376{
e8ef3da7 1377 {
f8dcd5ca 1378 LOCK2(cs_main, cs_wallet);
7d9d134b 1379 LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
e8ef3da7
WL
1380 {
1381 // This is only to keep the database open to defeat the auto-flush for the
1382 // duration of this scope. This is the only place where this optimization
1383 // maybe makes sense; please don't do it anywhere else.
1384 CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
1385
1386 // Take key pair from key pool so it won't be used again
1387 reservekey.KeepKey();
1388
1389 // Add tx to wallet, because if it has change it's also ours,
1390 // otherwise just for transaction history.
1391 AddToWallet(wtxNew);
1392
93a18a36 1393 // Notify that old coins are spent
e8ef3da7
WL
1394 set<CWalletTx*> setCoins;
1395 BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
1396 {
1397 CWalletTx &coin = mapWallet[txin.prevout.hash];
4c6e2295 1398 coin.BindWallet(this);
fe4a6550 1399 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
e8ef3da7
WL
1400 }
1401
1402 if (fFileBacked)
1403 delete pwalletdb;
1404 }
1405
1406 // Track how many getdata requests our transaction gets
6cc4a62c 1407 mapRequestCount[wtxNew.GetHash()] = 0;
e8ef3da7
WL
1408
1409 // Broadcast
b1f15b21 1410 if (!wtxNew.AcceptToMemoryPool(false))
e8ef3da7
WL
1411 {
1412 // This must not fail. The transaction has already been signed and recorded.
881a85a2 1413 LogPrintf("CommitTransaction() : Error: Transaction not valid");
e8ef3da7
WL
1414 return false;
1415 }
1416 wtxNew.RelayWalletTransaction();
1417 }
e8ef3da7
WL
1418 return true;
1419}
1420
1421
1422
1423
ca2c83da 1424string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew)
e8ef3da7
WL
1425{
1426 CReserveKey reservekey(this);
51ed9ec9 1427 int64_t nFeeRequired;
6cc4a62c
GA
1428
1429 if (IsLocked())
e8ef3da7 1430 {
6b3783a9 1431 string strError = _("Error: Wallet locked, unable to create transaction!");
7d9d134b 1432 LogPrintf("SendMoney() : %s", strError);
6cc4a62c
GA
1433 return strError;
1434 }
1f00f4e9
GA
1435 string strError;
1436 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
6cc4a62c 1437 {
6cc4a62c 1438 if (nValue + nFeeRequired > GetBalance())
7d9d134b
WL
1439 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));
1440 LogPrintf("SendMoney() : %s\n", strError);
6cc4a62c 1441 return strError;
e8ef3da7
WL
1442 }
1443
e8ef3da7 1444 if (!CommitTransaction(wtxNew, reservekey))
6b3783a9 1445 return _("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
e8ef3da7 1446
e8ef3da7
WL
1447 return "";
1448}
1449
1450
1451
ca2c83da 1452string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nValue, CWalletTx& wtxNew)
e8ef3da7
WL
1453{
1454 // Check amount
1455 if (nValue <= 0)
1456 return _("Invalid amount");
c6cb21d1 1457 if (nValue > GetBalance())
e8ef3da7
WL
1458 return _("Insufficient funds");
1459
ff0ee876 1460 // Parse Bitcoin address
e8ef3da7 1461 CScript scriptPubKey;
10254401 1462 scriptPubKey.SetDestination(address);
e8ef3da7 1463
ca2c83da 1464 return SendMoney(scriptPubKey, nValue, wtxNew);
e8ef3da7
WL
1465}
1466
1467
1468
1469
eed1785f 1470DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
e8ef3da7
WL
1471{
1472 if (!fFileBacked)
4f76be1d 1473 return DB_LOAD_OK;
e8ef3da7 1474 fFirstRunRet = false;
eed1785f 1475 DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
d764d916 1476 if (nLoadWalletRet == DB_NEED_REWRITE)
9e9869d0 1477 {
d764d916
GA
1478 if (CDB::Rewrite(strWalletFile, "\x04pool"))
1479 {
012ca1c9 1480 LOCK(cs_wallet);
d764d916
GA
1481 setKeyPool.clear();
1482 // Note: can't top-up keypool here, because wallet is locked.
1483 // User will be prompted to unlock wallet the next operation
1484 // the requires a new key.
1485 }
9e9869d0
PW
1486 }
1487
7ec55267
MC
1488 if (nLoadWalletRet != DB_LOAD_OK)
1489 return nLoadWalletRet;
fd61d6f5 1490 fFirstRunRet = !vchDefaultKey.IsValid();
e8ef3da7 1491
39278369
CL
1492 uiInterface.LoadWallet(this);
1493
116df55e 1494 return DB_LOAD_OK;
e8ef3da7
WL
1495}
1496
ae3d0aba 1497
518f3bda
JG
1498DBErrors CWallet::ZapWalletTx()
1499{
1500 if (!fFileBacked)
1501 return DB_LOAD_OK;
1502 DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this);
1503 if (nZapWalletTxRet == DB_NEED_REWRITE)
1504 {
1505 if (CDB::Rewrite(strWalletFile, "\x04pool"))
1506 {
1507 LOCK(cs_wallet);
1508 setKeyPool.clear();
1509 // Note: can't top-up keypool here, because wallet is locked.
1510 // User will be prompted to unlock wallet the next operation
1511 // the requires a new key.
1512 }
1513 }
1514
1515 if (nZapWalletTxRet != DB_LOAD_OK)
1516 return nZapWalletTxRet;
1517
1518 return DB_LOAD_OK;
1519}
1520
1521
a41d5fe0 1522bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
ae3d0aba 1523{
ca4cf5cf
GA
1524 bool fUpdated = false;
1525 {
1526 LOCK(cs_wallet); // mapAddressBook
1527 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
1528 fUpdated = mi != mapAddressBook.end();
1529 mapAddressBook[address].name = strName;
1530 if (!strPurpose.empty()) /* update purpose only if requested */
1531 mapAddressBook[address].purpose = strPurpose;
1532 }
dcd0b077 1533 NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
ca4cf5cf 1534 strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
ae3d0aba
WL
1535 if (!fFileBacked)
1536 return false;
a41d5fe0
GA
1537 if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
1538 return false;
10254401 1539 return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
ae3d0aba
WL
1540}
1541
a41d5fe0 1542bool CWallet::DelAddressBook(const CTxDestination& address)
ae3d0aba 1543{
b10e1470 1544 {
ca4cf5cf
GA
1545 LOCK(cs_wallet); // mapAddressBook
1546
1547 if(fFileBacked)
b10e1470 1548 {
ca4cf5cf
GA
1549 // Delete destdata tuples associated with address
1550 std::string strAddress = CBitcoinAddress(address).ToString();
1551 BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
1552 {
1553 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
1554 }
b10e1470 1555 }
ca4cf5cf 1556 mapAddressBook.erase(address);
b10e1470
WL
1557 }
1558
dcd0b077 1559 NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
ca4cf5cf 1560
ae3d0aba
WL
1561 if (!fFileBacked)
1562 return false;
a41d5fe0 1563 CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
10254401 1564 return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
ae3d0aba
WL
1565}
1566
fd61d6f5 1567bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
ae3d0aba
WL
1568{
1569 if (fFileBacked)
1570 {
1571 if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
1572 return false;
1573 }
1574 vchDefaultKey = vchPubKey;
1575 return true;
1576}
1577
37971fcc
GA
1578//
1579// Mark old keypool keys as used,
1580// and generate all new keys
1581//
1582bool CWallet::NewKeyPool()
1583{
37971fcc 1584 {
f8dcd5ca 1585 LOCK(cs_wallet);
37971fcc 1586 CWalletDB walletdb(strWalletFile);
51ed9ec9 1587 BOOST_FOREACH(int64_t nIndex, setKeyPool)
37971fcc
GA
1588 walletdb.ErasePool(nIndex);
1589 setKeyPool.clear();
1590
1591 if (IsLocked())
1592 return false;
1593
51ed9ec9 1594 int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
37971fcc
GA
1595 for (int i = 0; i < nKeys; i++)
1596 {
51ed9ec9 1597 int64_t nIndex = i+1;
37971fcc
GA
1598 walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
1599 setKeyPool.insert(nIndex);
1600 }
f48742c2 1601 LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
37971fcc
GA
1602 }
1603 return true;
1604}
1605
13dd2d09 1606bool CWallet::TopUpKeyPool(unsigned int kpSize)
e8ef3da7 1607{
e8ef3da7 1608 {
f8dcd5ca
PW
1609 LOCK(cs_wallet);
1610
4e87d341
MC
1611 if (IsLocked())
1612 return false;
1613
e8ef3da7
WL
1614 CWalletDB walletdb(strWalletFile);
1615
1616 // Top up key pool
13dd2d09
JG
1617 unsigned int nTargetSize;
1618 if (kpSize > 0)
1619 nTargetSize = kpSize;
1620 else
51ed9ec9 1621 nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
13dd2d09 1622
faf705a4 1623 while (setKeyPool.size() < (nTargetSize + 1))
e8ef3da7 1624 {
51ed9ec9 1625 int64_t nEnd = 1;
e8ef3da7
WL
1626 if (!setKeyPool.empty())
1627 nEnd = *(--setKeyPool.end()) + 1;
1628 if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
4e87d341 1629 throw runtime_error("TopUpKeyPool() : writing generated key failed");
e8ef3da7 1630 setKeyPool.insert(nEnd);
783b182c 1631 LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
e8ef3da7 1632 }
4e87d341
MC
1633 }
1634 return true;
1635}
1636
51ed9ec9 1637void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
4e87d341
MC
1638{
1639 nIndex = -1;
fd61d6f5 1640 keypool.vchPubKey = CPubKey();
4e87d341 1641 {
f8dcd5ca
PW
1642 LOCK(cs_wallet);
1643
4e87d341
MC
1644 if (!IsLocked())
1645 TopUpKeyPool();
e8ef3da7
WL
1646
1647 // Get the oldest key
4e87d341
MC
1648 if(setKeyPool.empty())
1649 return;
1650
1651 CWalletDB walletdb(strWalletFile);
1652
e8ef3da7
WL
1653 nIndex = *(setKeyPool.begin());
1654 setKeyPool.erase(setKeyPool.begin());
1655 if (!walletdb.ReadPool(nIndex, keypool))
1656 throw runtime_error("ReserveKeyFromKeyPool() : read failed");
fd61d6f5 1657 if (!HaveKey(keypool.vchPubKey.GetID()))
e8ef3da7 1658 throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
fd61d6f5 1659 assert(keypool.vchPubKey.IsValid());
f48742c2 1660 LogPrintf("keypool reserve %d\n", nIndex);
e8ef3da7
WL
1661 }
1662}
1663
51ed9ec9 1664void CWallet::KeepKey(int64_t nIndex)
e8ef3da7
WL
1665{
1666 // Remove from key pool
1667 if (fFileBacked)
1668 {
1669 CWalletDB walletdb(strWalletFile);
6cc4a62c 1670 walletdb.ErasePool(nIndex);
e8ef3da7 1671 }
f48742c2 1672 LogPrintf("keypool keep %d\n", nIndex);
e8ef3da7
WL
1673}
1674
51ed9ec9 1675void CWallet::ReturnKey(int64_t nIndex)
e8ef3da7
WL
1676{
1677 // Return to key pool
f8dcd5ca
PW
1678 {
1679 LOCK(cs_wallet);
e8ef3da7 1680 setKeyPool.insert(nIndex);
f8dcd5ca 1681 }
f48742c2 1682 LogPrintf("keypool return %d\n", nIndex);
e8ef3da7
WL
1683}
1684
71ac5052 1685bool CWallet::GetKeyFromPool(CPubKey& result)
e8ef3da7 1686{
51ed9ec9 1687 int64_t nIndex = 0;
e8ef3da7 1688 CKeyPool keypool;
7db3b75b 1689 {
f8dcd5ca 1690 LOCK(cs_wallet);
ed02c95d
GA
1691 ReserveKeyFromKeyPool(nIndex, keypool);
1692 if (nIndex == -1)
7db3b75b 1693 {
ed02c95d
GA
1694 if (IsLocked()) return false;
1695 result = GenerateNewKey();
7db3b75b
GA
1696 return true;
1697 }
ed02c95d
GA
1698 KeepKey(nIndex);
1699 result = keypool.vchPubKey;
7db3b75b 1700 }
7db3b75b 1701 return true;
e8ef3da7
WL
1702}
1703
51ed9ec9 1704int64_t CWallet::GetOldestKeyPoolTime()
e8ef3da7 1705{
51ed9ec9 1706 int64_t nIndex = 0;
e8ef3da7
WL
1707 CKeyPool keypool;
1708 ReserveKeyFromKeyPool(nIndex, keypool);
4e87d341
MC
1709 if (nIndex == -1)
1710 return GetTime();
e8ef3da7
WL
1711 ReturnKey(nIndex);
1712 return keypool.nTime;
1713}
1714
51ed9ec9 1715std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
22dfd735 1716{
51ed9ec9 1717 map<CTxDestination, int64_t> balances;
22dfd735 1718
1719 {
1720 LOCK(cs_wallet);
1721 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1722 {
1723 CWalletTx *pcoin = &walletEntry.second;
1724
0542619d 1725 if (!IsFinalTx(*pcoin) || !pcoin->IsTrusted())
22dfd735 1726 continue;
1727
1728 if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1729 continue;
1730
1731 int nDepth = pcoin->GetDepthInMainChain();
1732 if (nDepth < (pcoin->IsFromMe() ? 0 : 1))
1733 continue;
1734
b1093efa 1735 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 1736 {
b1093efa 1737 CTxDestination addr;
22dfd735 1738 if (!IsMine(pcoin->vout[i]))
1739 continue;
b1093efa
GM
1740 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
1741 continue;
22dfd735 1742
93a18a36 1743 int64_t n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
22dfd735 1744
22dfd735 1745 if (!balances.count(addr))
1746 balances[addr] = 0;
1747 balances[addr] += n;
1748 }
1749 }
1750 }
1751
1752 return balances;
1753}
1754
b1093efa 1755set< set<CTxDestination> > CWallet::GetAddressGroupings()
22dfd735 1756{
95691680 1757 AssertLockHeld(cs_wallet); // mapWallet
b1093efa
GM
1758 set< set<CTxDestination> > groupings;
1759 set<CTxDestination> grouping;
22dfd735 1760
1761 BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1762 {
1763 CWalletTx *pcoin = &walletEntry.second;
1764
a3fad211 1765 if (pcoin->vin.size() > 0)
22dfd735 1766 {
a3fad211 1767 bool any_mine = false;
22dfd735 1768 // group all input addresses with each other
1769 BOOST_FOREACH(CTxIn txin, pcoin->vin)
b1093efa
GM
1770 {
1771 CTxDestination address;
a3fad211
GM
1772 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
1773 continue;
b1093efa
GM
1774 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
1775 continue;
1776 grouping.insert(address);
a3fad211 1777 any_mine = true;
b1093efa 1778 }
22dfd735 1779
1780 // group change with input addresses
a3fad211
GM
1781 if (any_mine)
1782 {
1783 BOOST_FOREACH(CTxOut txout, pcoin->vout)
1784 if (IsChange(txout))
1785 {
1786 CTxDestination txoutAddr;
1787 if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
1788 continue;
1789 grouping.insert(txoutAddr);
1790 }
1791 }
1792 if (grouping.size() > 0)
1793 {
1794 groupings.insert(grouping);
1795 grouping.clear();
1796 }
22dfd735 1797 }
1798
1799 // group lone addrs by themselves
b1093efa 1800 for (unsigned int i = 0; i < pcoin->vout.size(); i++)
22dfd735 1801 if (IsMine(pcoin->vout[i]))
1802 {
b1093efa
GM
1803 CTxDestination address;
1804 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
1805 continue;
1806 grouping.insert(address);
22dfd735 1807 groupings.insert(grouping);
1808 grouping.clear();
1809 }
1810 }
1811
b1093efa
GM
1812 set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
1813 map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
1814 BOOST_FOREACH(set<CTxDestination> grouping, groupings)
22dfd735 1815 {
1816 // make a set of all the groups hit by this new group
b1093efa
GM
1817 set< set<CTxDestination>* > hits;
1818 map< CTxDestination, set<CTxDestination>* >::iterator it;
1819 BOOST_FOREACH(CTxDestination address, grouping)
22dfd735 1820 if ((it = setmap.find(address)) != setmap.end())
1821 hits.insert((*it).second);
1822
1823 // merge all hit groups into a new single group and delete old groups
b1093efa
GM
1824 set<CTxDestination>* merged = new set<CTxDestination>(grouping);
1825 BOOST_FOREACH(set<CTxDestination>* hit, hits)
22dfd735 1826 {
1827 merged->insert(hit->begin(), hit->end());
1828 uniqueGroupings.erase(hit);
1829 delete hit;
1830 }
1831 uniqueGroupings.insert(merged);
1832
1833 // update setmap
b1093efa 1834 BOOST_FOREACH(CTxDestination element, *merged)
22dfd735 1835 setmap[element] = merged;
1836 }
1837
b1093efa
GM
1838 set< set<CTxDestination> > ret;
1839 BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
22dfd735 1840 {
1841 ret.insert(*uniqueGrouping);
1842 delete uniqueGrouping;
1843 }
1844
1845 return ret;
1846}
1847
3624356e
GA
1848set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
1849{
95691680 1850 AssertLockHeld(cs_wallet); // mapWallet
3624356e
GA
1851 set<CTxDestination> result;
1852 BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
1853 {
1854 const CTxDestination& address = item.first;
1855 const string& strName = item.second.name;
1856 if (strName == strAccount)
1857 result.insert(address);
1858 }
1859 return result;
1860}
1861
360cfe14 1862bool CReserveKey::GetReservedKey(CPubKey& pubkey)
e8ef3da7
WL
1863{
1864 if (nIndex == -1)
1865 {
1866 CKeyPool keypool;
1867 pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
0d7b28e5
MC
1868 if (nIndex != -1)
1869 vchPubKey = keypool.vchPubKey;
360cfe14
PW
1870 else {
1871 if (pwallet->vchDefaultKey.IsValid()) {
881a85a2 1872 LogPrintf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
360cfe14
PW
1873 vchPubKey = pwallet->vchDefaultKey;
1874 } else
1875 return false;
cee69980 1876 }
e8ef3da7 1877 }
fd61d6f5 1878 assert(vchPubKey.IsValid());
360cfe14
PW
1879 pubkey = vchPubKey;
1880 return true;
e8ef3da7
WL
1881}
1882
1883void CReserveKey::KeepKey()
1884{
1885 if (nIndex != -1)
1886 pwallet->KeepKey(nIndex);
1887 nIndex = -1;
fd61d6f5 1888 vchPubKey = CPubKey();
e8ef3da7
WL
1889}
1890
1891void CReserveKey::ReturnKey()
1892{
1893 if (nIndex != -1)
1894 pwallet->ReturnKey(nIndex);
1895 nIndex = -1;
fd61d6f5 1896 vchPubKey = CPubKey();
e8ef3da7 1897}
ae3d0aba 1898
434e4273 1899void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
30ab2c9c
PW
1900{
1901 setAddress.clear();
1902
1903 CWalletDB walletdb(strWalletFile);
1904
f8dcd5ca 1905 LOCK2(cs_main, cs_wallet);
51ed9ec9 1906 BOOST_FOREACH(const int64_t& id, setKeyPool)
30ab2c9c
PW
1907 {
1908 CKeyPool keypool;
1909 if (!walletdb.ReadPool(id, keypool))
1910 throw runtime_error("GetAllReserveKeyHashes() : read failed");
fd61d6f5 1911 assert(keypool.vchPubKey.IsValid());
10254401
PW
1912 CKeyID keyID = keypool.vchPubKey.GetID();
1913 if (!HaveKey(keyID))
30ab2c9c 1914 throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
10254401 1915 setAddress.insert(keyID);
30ab2c9c
PW
1916 }
1917}
fe4a6550
WL
1918
1919void CWallet::UpdatedTransaction(const uint256 &hashTx)
1920{
1921 {
1922 LOCK(cs_wallet);
1923 // Only notify UI if this transaction is in this wallet
1924 map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
1925 if (mi != mapWallet.end())
1926 NotifyTransactionChanged(this, hashTx, CT_UPDATED);
1927 }
1928}
fdbb537d
JG
1929
1930void CWallet::LockCoin(COutPoint& output)
1931{
95691680 1932 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
1933 setLockedCoins.insert(output);
1934}
1935
1936void CWallet::UnlockCoin(COutPoint& output)
1937{
95691680 1938 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
1939 setLockedCoins.erase(output);
1940}
1941
1942void CWallet::UnlockAllCoins()
1943{
95691680 1944 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
1945 setLockedCoins.clear();
1946}
1947
1948bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
1949{
95691680 1950 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
1951 COutPoint outpt(hash, n);
1952
1953 return (setLockedCoins.count(outpt) > 0);
1954}
1955
1956void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
1957{
95691680 1958 AssertLockHeld(cs_wallet); // setLockedCoins
fdbb537d
JG
1959 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
1960 it != setLockedCoins.end(); it++) {
1961 COutPoint outpt = (*it);
1962 vOutpts.push_back(outpt);
1963 }
1964}
1965
51ed9ec9 1966void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
95691680 1967 AssertLockHeld(cs_wallet); // mapKeyMetadata
434e4273
PW
1968 mapKeyBirth.clear();
1969
1970 // get birth times for keys with metadata
1971 for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
1972 if (it->second.nCreateTime)
1973 mapKeyBirth[it->first] = it->second.nCreateTime;
1974
1975 // map in which we'll infer heights of other keys
4c6d41b8 1976 CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
434e4273
PW
1977 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
1978 std::set<CKeyID> setKeys;
1979 GetKeys(setKeys);
1980 BOOST_FOREACH(const CKeyID &keyid, setKeys) {
1981 if (mapKeyBirth.count(keyid) == 0)
1982 mapKeyFirstBlock[keyid] = pindexMax;
1983 }
1984 setKeys.clear();
1985
1986 // if there are no such keys, we're done
1987 if (mapKeyFirstBlock.empty())
1988 return;
1989
1990 // find first block that affects those keys, if there are any left
1991 std::vector<CKeyID> vAffected;
1992 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
1993 // iterate over all wallet transactions...
1994 const CWalletTx &wtx = (*it).second;
1995 std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
4c6d41b8 1996 if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
434e4273
PW
1997 // ... which are already in a block
1998 int nHeight = blit->second->nHeight;
1999 BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
2000 // iterate over all their outputs
2001 ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected);
2002 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
2003 // ... and all their affected keys
2004 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
2005 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
2006 rit->second = blit->second;
2007 }
2008 vAffected.clear();
2009 }
2010 }
2011 }
2012
2013 // Extract block timestamps for those keys
2014 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
2015 mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
2016}
b10e1470
WL
2017
2018bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2019{
8476d5d4
CL
2020 if (boost::get<CNoDestination>(&dest))
2021 return false;
2022
b10e1470
WL
2023 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2024 if (!fFileBacked)
2025 return true;
2026 return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
2027}
2028
2029bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
2030{
2031 if (!mapAddressBook[dest].destdata.erase(key))
2032 return false;
2033 if (!fFileBacked)
2034 return true;
2035 return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
2036}
2037
2038bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2039{
2040 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2041 return true;
2042}
2043
2044bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
2045{
2046 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
2047 if(i != mapAddressBook.end())
2048 {
2049 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
2050 if(j != i->second.destdata.end())
2051 {
2052 if(value)
2053 *value = j->second;
2054 return true;
2055 }
2056 }
2057 return false;
2058}
This page took 0.47657 seconds and 4 git commands to generate.