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