Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "wallet/wallet.h"
7 :
8 : #include "base58.h"
9 : #include "checkpoints.h"
10 : #include "chain.h"
11 : #include "coincontrol.h"
12 : #include "consensus/consensus.h"
13 : #include "consensus/validation.h"
14 : #include "key.h"
15 : #include "keystore.h"
16 : #include "main.h"
17 : #include "net.h"
18 : #include "policy/policy.h"
19 : #include "primitives/block.h"
20 : #include "primitives/transaction.h"
21 : #include "script/script.h"
22 : #include "script/sign.h"
23 : #include "timedata.h"
24 : #include "txmempool.h"
25 : #include "util.h"
26 : #include "utilmoneystr.h"
27 :
28 : #include <assert.h>
29 :
30 : #include <boost/algorithm/string/replace.hpp>
31 : #include <boost/filesystem.hpp>
32 : #include <boost/thread.hpp>
33 :
34 : using namespace std;
35 :
36 : /**
37 : * Settings
38 : */
39 : CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
40 : CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
41 : unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
42 : bool bSpendZeroConfChange = true;
43 : bool fSendFreeTransactions = false;
44 : bool fPayAtLeastCustomFee = true;
45 :
46 : /**
47 : * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
48 : * Override with -mintxfee
49 : */
50 96 : CFeeRate CWallet::minTxFee = CFeeRate(1000);
51 :
52 : /** @defgroup mapWallet
53 : *
54 : * @{
55 : */
56 :
57 : struct CompareValueOnly
58 : {
59 0 : bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
60 : const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
61 : {
62 0 : return t1.first < t2.first;
63 : }
64 : };
65 :
66 0 : std::string COutput::ToString() const
67 : {
68 0 : return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
69 : }
70 :
71 2093 : const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
72 : {
73 2093 : LOCK(cs_wallet);
74 4186 : std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
75 4186 : if (it == mapWallet.end())
76 : return NULL;
77 2093 : return &(it->second);
78 : }
79 :
80 1056 : CPubKey CWallet::GenerateNewKey()
81 : {
82 1056 : AssertLockHeld(cs_wallet); // mapKeyMetadata
83 2112 : bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
84 :
85 : CKey secret;
86 1056 : secret.MakeNewKey(fCompressed);
87 :
88 : // Compressed public keys were introduced in version 0.6.0
89 1056 : if (fCompressed)
90 949 : SetMinVersion(FEATURE_COMPRPUBKEY);
91 :
92 1056 : CPubKey pubkey = secret.GetPubKey();
93 1056 : assert(secret.VerifyPubKey(pubkey));
94 :
95 : // Create new metadata
96 1056 : int64_t nCreationTime = GetTime();
97 1056 : mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
98 1056 : if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
99 42 : nTimeFirstKey = nCreationTime;
100 :
101 1056 : if (!AddKeyPubKey(secret, pubkey))
102 0 : throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
103 1056 : return pubkey;
104 : }
105 :
106 1393 : bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
107 : {
108 1393 : AssertLockHeld(cs_wallet); // mapKeyMetadata
109 1393 : if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
110 : return false;
111 :
112 : // check if we need to remove from watch-only
113 : CScript script;
114 5572 : script = GetScriptForDestination(pubkey.GetID());
115 1393 : if (HaveWatchOnly(script))
116 0 : RemoveWatchOnly(script);
117 2786 : script = GetScriptForRawPubKey(pubkey);
118 1393 : if (HaveWatchOnly(script))
119 0 : RemoveWatchOnly(script);
120 :
121 1393 : if (!fFileBacked)
122 : return true;
123 1393 : if (!IsCrypted()) {
124 : return CWalletDB(strWalletFile).WriteKey(pubkey,
125 : secret.GetPrivKey(),
126 5396 : mapKeyMetadata[pubkey.GetID()]);
127 : }
128 : return true;
129 : }
130 :
131 65 : bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
132 : const vector<unsigned char> &vchCryptedSecret)
133 : {
134 65 : if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
135 : return false;
136 65 : if (!fFileBacked)
137 : return true;
138 : {
139 65 : LOCK(cs_wallet);
140 65 : if (pwalletdbEncryption)
141 : return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
142 : vchCryptedSecret,
143 21 : mapKeyMetadata[vchPubKey.GetID()]);
144 : else
145 : return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
146 : vchCryptedSecret,
147 132 : mapKeyMetadata[vchPubKey.GetID()]);
148 : }
149 : return false;
150 : }
151 :
152 2620 : bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
153 : {
154 2620 : AssertLockHeld(cs_wallet); // mapKeyMetadata
155 2620 : if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
156 159 : nTimeFirstKey = meta.nCreateTime;
157 :
158 2620 : mapKeyMetadata[pubkey.GetID()] = meta;
159 2620 : return true;
160 : }
161 :
162 22 : bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
163 : {
164 22 : return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
165 : }
166 :
167 9 : bool CWallet::AddCScript(const CScript& redeemScript)
168 : {
169 9 : if (!CCryptoKeyStore::AddCScript(redeemScript))
170 : return false;
171 9 : if (!fFileBacked)
172 : return true;
173 36 : return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
174 : }
175 :
176 3 : bool CWallet::LoadCScript(const CScript& redeemScript)
177 : {
178 : /* A sanity check was added in pull #3843 to avoid adding redeemScripts
179 : * that never can be redeemed. However, old wallets may still contain
180 : * these. Do not add them to the wallet and warn. */
181 6 : if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
182 : {
183 0 : std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString();
184 0 : 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",
185 0 : __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
186 0 : return true;
187 : }
188 :
189 3 : return CCryptoKeyStore::AddCScript(redeemScript);
190 : }
191 :
192 4 : bool CWallet::AddWatchOnly(const CScript &dest)
193 : {
194 4 : if (!CCryptoKeyStore::AddWatchOnly(dest))
195 : return false;
196 4 : nTimeFirstKey = 1; // No birthday information for watch-only keys.
197 4 : NotifyWatchonlyChanged(true);
198 4 : if (!fFileBacked)
199 : return true;
200 12 : return CWalletDB(strWalletFile).WriteWatchOnly(dest);
201 : }
202 :
203 0 : bool CWallet::RemoveWatchOnly(const CScript &dest)
204 : {
205 0 : AssertLockHeld(cs_wallet);
206 0 : if (!CCryptoKeyStore::RemoveWatchOnly(dest))
207 : return false;
208 0 : if (!HaveWatchOnly())
209 0 : NotifyWatchonlyChanged(false);
210 0 : if (fFileBacked)
211 0 : if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
212 : return false;
213 :
214 : return true;
215 : }
216 :
217 2 : bool CWallet::LoadWatchOnly(const CScript &dest)
218 : {
219 2 : return CCryptoKeyStore::AddWatchOnly(dest);
220 : }
221 :
222 2 : bool CWallet::Unlock(const SecureString& strWalletPassphrase)
223 : {
224 2 : CCrypter crypter;
225 : CKeyingMaterial vMasterKey;
226 :
227 : {
228 2 : LOCK(cs_wallet);
229 18 : BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
230 : {
231 2 : if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
232 : return false;
233 2 : if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
234 : continue; // try another master key
235 2 : if (CCryptoKeyStore::Unlock(vMasterKey))
236 : return true;
237 : }
238 : }
239 2 : return false;
240 : }
241 :
242 0 : bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
243 : {
244 0 : bool fWasLocked = IsLocked();
245 :
246 : {
247 0 : LOCK(cs_wallet);
248 0 : Lock();
249 :
250 0 : CCrypter crypter;
251 : CKeyingMaterial vMasterKey;
252 0 : BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
253 : {
254 0 : if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
255 : return false;
256 0 : if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
257 : return false;
258 0 : if (CCryptoKeyStore::Unlock(vMasterKey))
259 : {
260 0 : int64_t nStartTime = GetTimeMillis();
261 0 : crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
262 0 : pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
263 :
264 0 : nStartTime = GetTimeMillis();
265 0 : crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
266 0 : pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
267 :
268 0 : if (pMasterKey.second.nDeriveIterations < 25000)
269 0 : pMasterKey.second.nDeriveIterations = 25000;
270 :
271 0 : LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
272 :
273 0 : if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
274 : return false;
275 0 : if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
276 : return false;
277 0 : CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
278 0 : if (fWasLocked)
279 0 : Lock();
280 : return true;
281 : }
282 : }
283 : }
284 :
285 0 : return false;
286 : }
287 :
288 87 : void CWallet::SetBestChain(const CBlockLocator& loc)
289 : {
290 87 : CWalletDB walletdb(strWalletFile);
291 87 : walletdb.WriteBestBlock(loc);
292 87 : }
293 :
294 987 : bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
295 : {
296 987 : LOCK(cs_wallet); // nWalletVersion
297 987 : if (nWalletVersion >= nVersion)
298 : return true;
299 :
300 : // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
301 37 : if (fExplicit && nVersion > nWalletMaxVersion)
302 0 : nVersion = FEATURE_LATEST;
303 :
304 37 : nWalletVersion = nVersion;
305 :
306 37 : if (nVersion > nWalletMaxVersion)
307 37 : nWalletMaxVersion = nVersion;
308 :
309 37 : if (fFileBacked)
310 : {
311 74 : CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
312 37 : if (nWalletVersion > 40000)
313 37 : pwalletdb->WriteMinVersion(nWalletVersion);
314 37 : if (!pwalletdbIn)
315 74 : delete pwalletdb;
316 : }
317 :
318 : return true;
319 : }
320 :
321 37 : bool CWallet::SetMaxVersion(int nVersion)
322 : {
323 37 : LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
324 : // cannot downgrade below current version
325 37 : if (nWalletVersion > nVersion)
326 : return false;
327 :
328 37 : nWalletMaxVersion = nVersion;
329 :
330 37 : return true;
331 : }
332 :
333 185 : set<uint256> CWallet::GetConflicts(const uint256& txid) const
334 : {
335 : set<uint256> result;
336 185 : AssertLockHeld(cs_wallet);
337 :
338 370 : std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
339 370 : if (it == mapWallet.end())
340 : return result;
341 185 : const CWalletTx& wtx = it->second;
342 :
343 : std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
344 :
345 2323 : BOOST_FOREACH(const CTxIn& txin, wtx.vin)
346 : {
347 466 : if (mapTxSpends.count(txin.prevout) <= 1)
348 : continue; // No conflict if zero or one spends
349 8 : range = mapTxSpends.equal_range(txin.prevout);
350 16 : for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
351 8 : result.insert(it->second);
352 : }
353 185 : return result;
354 : }
355 :
356 188 : void CWallet::Flush(bool shutdown)
357 : {
358 188 : bitdb.Flush(shutdown);
359 188 : }
360 :
361 94 : bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
362 : {
363 94 : if (!bitdb.Open(GetDataDir()))
364 : {
365 : // try moving the database env out of the way
366 0 : boost::filesystem::path pathDatabase = GetDataDir() / "database";
367 0 : boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
368 : try {
369 : boost::filesystem::rename(pathDatabase, pathDatabaseBak);
370 0 : LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
371 0 : } catch (const boost::filesystem::filesystem_error&) {
372 : // failure is ok (well, not really, but it's not worse than what we started with)
373 : }
374 :
375 : // try again
376 0 : if (!bitdb.Open(GetDataDir())) {
377 : // if it still fails, it probably means we can't even create the database env
378 0 : string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
379 : errorString += msg;
380 0 : return true;
381 : }
382 : }
383 :
384 282 : if (GetBoolArg("-salvagewallet", false))
385 : {
386 : // Recover readable keypairs:
387 0 : if (!CWalletDB::Recover(bitdb, walletFile, true))
388 : return false;
389 : }
390 :
391 282 : if (boost::filesystem::exists(GetDataDir() / walletFile))
392 : {
393 57 : CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
394 57 : if (r == CDBEnv::RECOVER_OK)
395 : {
396 0 : warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
397 : " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
398 : " your balance or transactions are incorrect you should"
399 0 : " restore from a backup."), GetDataDir());
400 : }
401 57 : if (r == CDBEnv::RECOVER_FAIL)
402 0 : errorString += _("wallet.dat corrupt, salvage failed");
403 : }
404 :
405 : return true;
406 : }
407 :
408 682 : void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
409 : {
410 : // We want all the wallet transactions in range to have the same metadata as
411 : // the oldest (smallest nOrderPos).
412 : // So: find smallest nOrderPos:
413 :
414 682 : int nMinOrderPos = std::numeric_limits<int>::max();
415 682 : const CWalletTx* copyFrom = NULL;
416 2052 : for (TxSpends::iterator it = range.first; it != range.second; ++it)
417 : {
418 688 : const uint256& hash = it->second;
419 688 : int n = mapWallet[hash].nOrderPos;
420 688 : if (n < nMinOrderPos)
421 : {
422 682 : nMinOrderPos = n;
423 682 : copyFrom = &mapWallet[hash];
424 : }
425 : }
426 : // Now copy data from copyFrom to rest:
427 1370 : for (TxSpends::iterator it = range.first; it != range.second; ++it)
428 : {
429 688 : const uint256& hash = it->second;
430 688 : CWalletTx* copyTo = &mapWallet[hash];
431 688 : if (copyFrom == copyTo) continue;
432 6 : if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
433 2 : copyTo->mapValue = copyFrom->mapValue;
434 2 : copyTo->vOrderForm = copyFrom->vOrderForm;
435 : // fTimeReceivedIsTxTime not copied on purpose
436 : // nTimeReceived not copied on purpose
437 2 : copyTo->nTimeSmart = copyFrom->nTimeSmart;
438 2 : copyTo->fFromMe = copyFrom->fFromMe;
439 2 : copyTo->strFromAccount = copyFrom->strFromAccount;
440 : // nOrderPos not copied on purpose
441 : // cached members not copied on purpose
442 : }
443 682 : }
444 :
445 : /**
446 : * Outpoint is spent if any non-conflicted transaction
447 : * spends it:
448 : */
449 16322 : bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
450 : {
451 : const COutPoint outpoint(hash, n);
452 : pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
453 32644 : range = mapTxSpends.equal_range(outpoint);
454 :
455 32647 : for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
456 : {
457 7345 : const uint256& wtxid = it->second;
458 14690 : std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
459 29380 : if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
460 : return true; // Spent
461 : }
462 : return false;
463 : }
464 :
465 682 : void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
466 : {
467 1364 : mapTxSpends.insert(make_pair(outpoint, wtxid));
468 :
469 : pair<TxSpends::iterator, TxSpends::iterator> range;
470 1364 : range = mapTxSpends.equal_range(outpoint);
471 682 : SyncMetaData(range);
472 682 : }
473 :
474 :
475 4360 : void CWallet::AddToSpends(const uint256& wtxid)
476 : {
477 8720 : assert(mapWallet.count(wtxid));
478 4360 : CWalletTx& thisTx = mapWallet[wtxid];
479 4360 : if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
480 4360 : return;
481 :
482 6522 : BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
483 682 : AddToSpends(txin.prevout, wtxid);
484 : }
485 :
486 1 : bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
487 : {
488 1 : if (IsCrypted())
489 : return false;
490 :
491 : CKeyingMaterial vMasterKey;
492 1 : RandAddSeedPerfmon();
493 :
494 1 : vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
495 1 : GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
496 :
497 2 : CMasterKey kMasterKey;
498 1 : RandAddSeedPerfmon();
499 :
500 1 : kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
501 1 : GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
502 :
503 2 : CCrypter crypter;
504 1 : int64_t nStartTime = GetTimeMillis();
505 1 : crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
506 1 : kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
507 :
508 1 : nStartTime = GetTimeMillis();
509 1 : crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
510 1 : kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
511 :
512 1 : if (kMasterKey.nDeriveIterations < 25000)
513 0 : kMasterKey.nDeriveIterations = 25000;
514 :
515 1 : LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
516 :
517 1 : if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
518 : return false;
519 1 : if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
520 : return false;
521 :
522 : {
523 1 : LOCK(cs_wallet);
524 1 : mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
525 1 : if (fFileBacked)
526 : {
527 1 : assert(!pwalletdbEncryption);
528 2 : pwalletdbEncryption = new CWalletDB(strWalletFile);
529 1 : if (!pwalletdbEncryption->TxnBegin()) {
530 0 : delete pwalletdbEncryption;
531 0 : pwalletdbEncryption = NULL;
532 0 : return false;
533 : }
534 1 : pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
535 : }
536 :
537 1 : if (!EncryptKeys(vMasterKey))
538 : {
539 0 : if (fFileBacked) {
540 0 : pwalletdbEncryption->TxnAbort();
541 0 : delete pwalletdbEncryption;
542 : }
543 : // We now probably have half of our keys encrypted in memory, and half not...
544 : // die and let the user reload the unencrypted wallet.
545 0 : assert(false);
546 : }
547 :
548 : // Encryption was introduced in version 0.4.0
549 1 : SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
550 :
551 1 : if (fFileBacked)
552 : {
553 1 : if (!pwalletdbEncryption->TxnCommit()) {
554 0 : delete pwalletdbEncryption;
555 : // We now have keys encrypted in memory, but not on disk...
556 : // die to avoid confusion and let the user reload the unencrypted wallet.
557 0 : assert(false);
558 : }
559 :
560 2 : delete pwalletdbEncryption;
561 1 : pwalletdbEncryption = NULL;
562 : }
563 :
564 1 : Lock();
565 1 : Unlock(strWalletPassphrase);
566 1 : NewKeyPool();
567 1 : Lock();
568 :
569 : // Need to completely rewrite the wallet file; if we don't, bdb might keep
570 : // bits of the unencrypted private key in slack space in the database file.
571 1 : CDB::Rewrite(strWalletFile);
572 :
573 : }
574 1 : NotifyStatusChanged(this);
575 :
576 : return true;
577 : }
578 :
579 1623 : int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
580 : {
581 1623 : AssertLockHeld(cs_wallet); // nOrderPosNext
582 1623 : int64_t nRet = nOrderPosNext++;
583 1623 : if (pwalletdb) {
584 1622 : pwalletdb->WriteOrderPosNext(nOrderPosNext);
585 : } else {
586 3 : CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
587 : }
588 1623 : return nRet;
589 : }
590 :
591 1379 : CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
592 : {
593 1379 : AssertLockHeld(cs_wallet); // mapWallet
594 1379 : CWalletDB walletdb(strWalletFile);
595 :
596 : // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
597 : TxItems txOrdered;
598 :
599 : // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
600 : // would make this much faster for applications that do this a lot.
601 174446 : for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
602 : {
603 84465 : CWalletTx* wtx = &((*it).second);
604 168930 : txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
605 : }
606 : acentries.clear();
607 1379 : walletdb.ListAccountCreditDebit(strAccount, acentries);
608 8274 : BOOST_FOREACH(CAccountingEntry& entry, acentries)
609 : {
610 0 : txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
611 : }
612 :
613 1379 : return txOrdered;
614 : }
615 :
616 7 : void CWallet::MarkDirty()
617 : {
618 : {
619 7 : LOCK(cs_wallet);
620 1092 : BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
621 175 : item.second.MarkDirty();
622 : }
623 7 : }
624 :
625 6856 : bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
626 : {
627 6856 : uint256 hash = wtxIn.GetHash();
628 :
629 6856 : if (fFromLoadWallet)
630 : {
631 2738 : mapWallet[hash] = wtxIn;
632 2738 : mapWallet[hash].BindWallet(this);
633 2738 : AddToSpends(hash);
634 : }
635 : else
636 : {
637 4118 : LOCK(cs_wallet);
638 : // Inserts only if not already there, returns tx inserted or tx found
639 20590 : pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
640 4118 : CWalletTx& wtx = (*ret.first).second;
641 : wtx.BindWallet(this);
642 4118 : bool fInsertedNew = ret.second;
643 4118 : if (fInsertedNew)
644 : {
645 1622 : wtx.nTimeReceived = GetAdjustedTime();
646 1622 : wtx.nOrderPos = IncOrderPosNext(pwalletdb);
647 :
648 1622 : wtx.nTimeSmart = wtx.nTimeReceived;
649 3244 : if (!wtxIn.hashBlock.IsNull())
650 : {
651 2718 : if (mapBlockIndex.count(wtxIn.hashBlock))
652 : {
653 1359 : int64_t latestNow = wtx.nTimeReceived;
654 1359 : int64_t latestEntry = 0;
655 : {
656 : // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
657 1359 : int64_t latestTolerated = latestNow + 300;
658 : std::list<CAccountingEntry> acentries;
659 4077 : TxItems txOrdered = OrderedTxItems(acentries);
660 2718 : for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
661 : {
662 2692 : CWalletTx *const pwtx = (*it).second.first;
663 2692 : if (pwtx == &wtx)
664 : continue;
665 1333 : CAccountingEntry *const pacentry = (*it).second.second;
666 : int64_t nSmartTime;
667 1333 : if (pwtx)
668 : {
669 1333 : nSmartTime = pwtx->nTimeSmart;
670 1333 : if (!nSmartTime)
671 0 : nSmartTime = pwtx->nTimeReceived;
672 : }
673 : else
674 0 : nSmartTime = pacentry->nTime;
675 1333 : if (nSmartTime <= latestTolerated)
676 : {
677 1333 : latestEntry = nSmartTime;
678 1333 : if (nSmartTime > latestNow)
679 0 : latestNow = nSmartTime;
680 : break;
681 : }
682 : }
683 : }
684 :
685 4077 : int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
686 2718 : wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
687 : }
688 : else
689 0 : LogPrintf("AddToWallet(): found %s in block %s not in index\n",
690 : wtxIn.GetHash().ToString(),
691 0 : wtxIn.hashBlock.ToString());
692 : }
693 1622 : AddToSpends(hash);
694 : }
695 :
696 4118 : bool fUpdated = false;
697 4118 : if (!fInsertedNew)
698 : {
699 : // Merge
700 4810 : if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
701 : {
702 258 : wtx.hashBlock = wtxIn.hashBlock;
703 258 : fUpdated = true;
704 : }
705 2496 : if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
706 : {
707 254 : wtx.nIndex = wtxIn.nIndex;
708 254 : fUpdated = true;
709 : }
710 2496 : if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
711 : {
712 0 : wtx.fFromMe = wtxIn.fFromMe;
713 0 : fUpdated = true;
714 : }
715 : }
716 :
717 : //// debug print
718 8236 : LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
719 :
720 : // Write to disk
721 4118 : if (fInsertedNew || fUpdated)
722 1880 : if (!wtx.WriteToDisk(pwalletdb))
723 0 : return false;
724 :
725 : // Break debit/credit balance caches:
726 : wtx.MarkDirty();
727 :
728 : // Notify UI of new or updated transaction
729 4118 : NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
730 :
731 : // notify an external script when a wallet transaction comes in or is updated
732 20590 : std::string strCmd = GetArg("-walletnotify", "");
733 :
734 4118 : if ( !strCmd.empty())
735 : {
736 0 : boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
737 0 : boost::thread t(runCommand, strCmd); // thread runs free
738 : }
739 :
740 : }
741 : return true;
742 : }
743 :
744 : /**
745 : * Add a transaction to the wallet, or update it.
746 : * pblock is optional, but should be provided if the transaction is known to be in a block.
747 : * If fUpdate is true, existing transactions will be updated.
748 : */
749 15139 : bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
750 : {
751 : {
752 15139 : AssertLockHeld(cs_wallet);
753 30278 : bool fExisted = mapWallet.count(tx.GetHash()) != 0;
754 15139 : if (fExisted && !fUpdate) return false;
755 26296 : if (fExisted || IsMine(tx) || IsFromMe(tx))
756 : {
757 3991 : CWalletTx wtx(this,tx);
758 :
759 : // Get merkle branch if transaction was found in a block
760 3991 : if (pblock)
761 3673 : wtx.SetMerkleBranch(*pblock);
762 :
763 : // Do not flush the wallet here for performance reasons
764 : // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
765 3991 : CWalletDB walletdb(strWalletFile, "r+", false);
766 :
767 7982 : return AddToWallet(wtx, false, &walletdb);
768 : }
769 : }
770 : return false;
771 : }
772 :
773 6697 : void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
774 : {
775 6697 : LOCK2(cs_main, cs_wallet);
776 6697 : if (!AddToWalletIfInvolvingMe(tx, pblock, true))
777 6697 : return; // Not one of ours
778 :
779 : // If a transaction changes 'conflicted' state, that changes the balance
780 : // available of the outputs it spends. So force those to be
781 : // recomputed, also:
782 22819 : BOOST_FOREACH(const CTxIn& txin, tx.vin)
783 : {
784 4518 : if (mapWallet.count(txin.prevout.hash))
785 855 : mapWallet[txin.prevout.hash].MarkDirty();
786 : }
787 : }
788 :
789 :
790 0 : isminetype CWallet::IsMine(const CTxIn &txin) const
791 : {
792 : {
793 0 : LOCK(cs_wallet);
794 0 : map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
795 0 : if (mi != mapWallet.end())
796 : {
797 0 : const CWalletTx& prev = (*mi).second;
798 0 : if (txin.prevout.n < prev.vout.size())
799 0 : return IsMine(prev.vout[txin.prevout.n]);
800 : }
801 : }
802 0 : return ISMINE_NO;
803 : }
804 :
805 13912 : CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
806 : {
807 : {
808 13912 : LOCK(cs_wallet);
809 27824 : map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
810 27824 : if (mi != mapWallet.end())
811 : {
812 1125 : const CWalletTx& prev = (*mi).second;
813 2250 : if (txin.prevout.n < prev.vout.size())
814 3375 : if (IsMine(prev.vout[txin.prevout.n]) & filter)
815 960 : return prev.vout[txin.prevout.n].nValue;
816 : }
817 : }
818 13432 : return 0;
819 : }
820 :
821 0 : isminetype CWallet::IsMine(const CTxOut& txout) const
822 : {
823 33687 : return ::IsMine(*this, txout.scriptPubKey);
824 : }
825 :
826 1505 : CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
827 : {
828 3010 : if (!MoneyRange(txout.nValue))
829 0 : throw std::runtime_error("CWallet::GetCredit(): value out of range");
830 1505 : return ((IsMine(txout) & filter) ? txout.nValue : 0);
831 : }
832 :
833 271 : bool CWallet::IsChange(const CTxOut& txout) const
834 : {
835 : // TODO: fix handling of 'change' outputs. The assumption is that any
836 : // payment to a script that is ours, but is not in the address book
837 : // is change. That assumption is likely to break when we implement multisignature
838 : // wallets that return change back into a multi-signature-protected address;
839 : // a better way of identifying which outputs are 'the send' and which are
840 : // 'the change' will need to be implemented (maybe extend CWalletTx to remember
841 : // which output, if any, was change).
842 271 : if (::IsMine(*this, txout.scriptPubKey))
843 : {
844 : CTxDestination address;
845 195 : if (!ExtractDestination(txout.scriptPubKey, address))
846 : return true;
847 :
848 195 : LOCK(cs_wallet);
849 390 : if (!mapAddressBook.count(address))
850 112 : return true;
851 : }
852 : return false;
853 : }
854 :
855 0 : CAmount CWallet::GetChange(const CTxOut& txout) const
856 : {
857 0 : if (!MoneyRange(txout.nValue))
858 0 : throw std::runtime_error("CWallet::GetChange(): value out of range");
859 0 : return (IsChange(txout) ? txout.nValue : 0);
860 : }
861 :
862 12643 : bool CWallet::IsMine(const CTransaction& tx) const
863 : {
864 139769 : BOOST_FOREACH(const CTxOut& txout, tx.vout)
865 13502 : if (IsMine(txout))
866 1486 : return true;
867 11157 : return false;
868 : }
869 :
870 0 : bool CWallet::IsFromMe(const CTransaction& tx) const
871 : {
872 11157 : return (GetDebit(tx, ISMINE_ALL) > 0);
873 : }
874 :
875 12773 : CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
876 : {
877 12773 : CAmount nDebit = 0;
878 147337 : BOOST_FOREACH(const CTxIn& txin, tx.vin)
879 : {
880 13912 : nDebit += GetDebit(txin, filter);
881 27824 : if (!MoneyRange(nDebit))
882 0 : throw std::runtime_error("CWallet::GetDebit(): value out of range");
883 : }
884 12773 : return nDebit;
885 : }
886 :
887 46 : CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
888 : {
889 46 : CAmount nCredit = 0;
890 668 : BOOST_FOREACH(const CTxOut& txout, tx.vout)
891 : {
892 73 : nCredit += GetCredit(txout, filter);
893 146 : if (!MoneyRange(nCredit))
894 0 : throw std::runtime_error("CWallet::GetCredit(): value out of range");
895 : }
896 46 : return nCredit;
897 : }
898 :
899 0 : CAmount CWallet::GetChange(const CTransaction& tx) const
900 : {
901 0 : CAmount nChange = 0;
902 0 : BOOST_FOREACH(const CTxOut& txout, tx.vout)
903 : {
904 0 : nChange += GetChange(txout);
905 0 : if (!MoneyRange(nChange))
906 0 : throw std::runtime_error("CWallet::GetChange(): value out of range");
907 : }
908 0 : return nChange;
909 : }
910 :
911 185 : int64_t CWalletTx::GetTxTime() const
912 : {
913 185 : int64_t n = nTimeSmart;
914 185 : return n ? n : nTimeReceived;
915 : }
916 :
917 0 : int CWalletTx::GetRequestCount() const
918 : {
919 : // Returns -1 if it wasn't being tracked
920 0 : int nRequests = -1;
921 : {
922 0 : LOCK(pwallet->cs_wallet);
923 0 : if (IsCoinBase())
924 : {
925 : // Generated block
926 0 : if (!hashBlock.IsNull())
927 : {
928 0 : map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
929 0 : if (mi != pwallet->mapRequestCount.end())
930 0 : nRequests = (*mi).second;
931 : }
932 : }
933 : else
934 : {
935 : // Did anyone request this transaction?
936 0 : map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
937 0 : if (mi != pwallet->mapRequestCount.end())
938 : {
939 0 : nRequests = (*mi).second;
940 :
941 : // How about the block it's in?
942 0 : if (nRequests == 0 && !hashBlock.IsNull())
943 : {
944 0 : map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
945 0 : if (mi != pwallet->mapRequestCount.end())
946 0 : nRequests = (*mi).second;
947 : else
948 : nRequests = 1; // If it's in someone else's block it must have got out
949 : }
950 : }
951 : }
952 : }
953 0 : return nRequests;
954 : }
955 :
956 1064 : void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
957 : list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
958 : {
959 1064 : nFee = 0;
960 : listReceived.clear();
961 : listSent.clear();
962 1064 : strSentAccount = strFromAccount;
963 :
964 : // Compute fee:
965 1064 : CAmount nDebit = GetDebit(filter);
966 1064 : if (nDebit > 0) // debit>0 means we signed/sent this transaction
967 : {
968 137 : CAmount nValueOut = GetValueOut();
969 137 : nFee = nDebit - nValueOut;
970 : }
971 :
972 : // Sent/received.
973 3596 : for (unsigned int i = 0; i < vout.size(); ++i)
974 : {
975 2532 : const CTxOut& txout = vout[i];
976 2532 : isminetype fIsMine = pwallet->IsMine(txout);
977 : // Only need to handle txouts if AT LEAST one of these is true:
978 : // 1) they debit from us (sent)
979 : // 2) the output is to us (received)
980 1266 : if (nDebit > 0)
981 : {
982 : // Don't report 'change' txouts
983 271 : if (pwallet->IsChange(txout))
984 172 : continue;
985 : }
986 995 : else if (!(fIsMine & filter))
987 : continue;
988 :
989 : // In either case, we need to get the destination address
990 : CTxDestination address;
991 1094 : if (!ExtractDestination(txout.scriptPubKey, address))
992 : {
993 0 : LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
994 0 : this->GetHash().ToString());
995 0 : address = CNoDestination();
996 : }
997 :
998 1094 : COutputEntry output = {address, txout.nValue, (int)i};
999 :
1000 : // If we are debited by the transaction, add the output as a "sent" entry
1001 1094 : if (nDebit > 0)
1002 : listSent.push_back(output);
1003 :
1004 : // If we are receiving the output, add it as a "received" entry
1005 1094 : if (fIsMine & filter)
1006 : listReceived.push_back(output);
1007 : }
1008 :
1009 1064 : }
1010 :
1011 745 : void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
1012 : CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
1013 : {
1014 745 : nReceived = nSent = nFee = 0;
1015 :
1016 : CAmount allFee;
1017 : string strSentAccount;
1018 : list<COutputEntry> listReceived;
1019 : list<COutputEntry> listSent;
1020 745 : GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
1021 :
1022 745 : if (strAccount == strSentAccount)
1023 : {
1024 1953 : BOOST_FOREACH(const COutputEntry& s, listSent)
1025 27 : nSent += s.amount;
1026 303 : nFee = allFee;
1027 : }
1028 : {
1029 745 : LOCK(pwallet->cs_wallet);
1030 8802 : BOOST_FOREACH(const COutputEntry& r, listReceived)
1031 : {
1032 1444 : if (pwallet->mapAddressBook.count(r.destination))
1033 : {
1034 172 : map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
1035 258 : if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
1036 56 : nReceived += r.amount;
1037 : }
1038 636 : else if (strAccount.empty())
1039 : {
1040 251 : nReceived += r.amount;
1041 : }
1042 : }
1043 : }
1044 745 : }
1045 :
1046 :
1047 4 : bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
1048 : {
1049 3768 : return pwalletdb->WriteTx(GetHash(), *this);
1050 : }
1051 :
1052 : /**
1053 : * Scan the block chain (starting in pindexStart) for transactions
1054 : * from or to us. If fUpdate is true, found transactions that already
1055 : * exist in the wallet will be updated.
1056 : */
1057 54 : int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
1058 : {
1059 54 : int ret = 0;
1060 54 : int64_t nNow = GetTime();
1061 54 : const CChainParams& chainParams = Params();
1062 :
1063 54 : CBlockIndex* pindex = pindexStart;
1064 : {
1065 54 : LOCK2(cs_main, cs_wallet);
1066 :
1067 : // no need to read and scan block, if block was created before
1068 : // our wallet birthday (as adjusted for block time variability)
1069 1820 : while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
1070 856 : pindex = chainActive.Next(pindex);
1071 :
1072 108 : ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1073 54 : double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
1074 54 : double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
1075 8243 : while (pindex)
1076 : {
1077 8189 : if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
1078 0 : ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
1079 :
1080 8189 : CBlock block;
1081 8189 : ReadBlockFromDisk(block, pindex);
1082 99786 : BOOST_FOREACH(CTransaction& tx, block.vtx)
1083 : {
1084 8442 : if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
1085 2138 : ret++;
1086 : }
1087 8189 : pindex = chainActive.Next(pindex);
1088 8189 : if (GetTime() >= nNow + 60) {
1089 0 : nNow = GetTime();
1090 0 : LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
1091 : }
1092 : }
1093 108 : ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
1094 : }
1095 54 : return ret;
1096 : }
1097 :
1098 95 : void CWallet::ReacceptWalletTransactions()
1099 : {
1100 : // If transactions aren't being broadcasted, don't let them into local mempool either
1101 95 : if (!fBroadcastTransactions)
1102 3 : return;
1103 92 : LOCK2(cs_main, cs_wallet);
1104 : std::map<int64_t, CWalletTx*> mapSorted;
1105 :
1106 : // Sort pending wallet transactions based on their initial wallet insertion order
1107 15738 : BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1108 : {
1109 2531 : const uint256& wtxid = item.first;
1110 2531 : CWalletTx& wtx = item.second;
1111 5062 : assert(wtx.GetHash() == wtxid);
1112 :
1113 5062 : int nDepth = wtx.GetDepthInMainChain();
1114 :
1115 2531 : if (!wtx.IsCoinBase() && nDepth < 0) {
1116 28 : mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
1117 : }
1118 : }
1119 :
1120 : // Try to add wallet transactions to memory pool
1121 622 : BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
1122 : {
1123 14 : CWalletTx& wtx = *(item.second);
1124 :
1125 14 : LOCK(mempool.cs);
1126 14 : wtx.AcceptToMemoryPool(false);
1127 : }
1128 : }
1129 :
1130 4172 : bool CWalletTx::RelayWalletTransaction()
1131 : {
1132 4172 : assert(pwallet->GetBroadcastTransactions());
1133 4172 : if (!IsCoinBase())
1134 : {
1135 264 : if (GetDepthInMainChain() == 0) {
1136 248 : LogPrintf("Relaying wtx %s\n", GetHash().ToString());
1137 248 : RelayTransaction((CTransaction)*this);
1138 124 : return true;
1139 : }
1140 : }
1141 : return false;
1142 : }
1143 :
1144 185 : set<uint256> CWalletTx::GetConflicts() const
1145 : {
1146 : set<uint256> result;
1147 185 : if (pwallet != NULL)
1148 : {
1149 185 : uint256 myHash = GetHash();
1150 370 : result = pwallet->GetConflicts(myHash);
1151 : result.erase(myHash);
1152 : }
1153 185 : return result;
1154 : }
1155 :
1156 149700 : CAmount CWalletTx::GetDebit(const isminefilter& filter) const
1157 : {
1158 299400 : if (vin.empty())
1159 : return 0;
1160 :
1161 8900 : CAmount debit = 0;
1162 8900 : if(filter & ISMINE_SPENDABLE)
1163 : {
1164 8642 : if (fDebitCached)
1165 7778 : debit += nDebitCached;
1166 : else
1167 : {
1168 864 : nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
1169 864 : fDebitCached = true;
1170 864 : debit += nDebitCached;
1171 : }
1172 : }
1173 8900 : if(filter & ISMINE_WATCH_ONLY)
1174 : {
1175 7763 : if(fWatchDebitCached)
1176 7011 : debit += nWatchDebitCached;
1177 : else
1178 : {
1179 752 : nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
1180 752 : fWatchDebitCached = true;
1181 752 : debit += nWatchDebitCached;
1182 : }
1183 : }
1184 8900 : return debit;
1185 : }
1186 :
1187 44 : CAmount CWalletTx::GetCredit(const isminefilter& filter) const
1188 : {
1189 : // Must wait until coinbase is safely deep enough in the chain before valuing it
1190 44 : if (IsCoinBase() && GetBlocksToMaturity() > 0)
1191 : return 0;
1192 :
1193 44 : int64_t credit = 0;
1194 44 : if (filter & ISMINE_SPENDABLE)
1195 : {
1196 : // GetBalance can assume transactions in mapWallet won't change
1197 44 : if (fCreditCached)
1198 0 : credit += nCreditCached;
1199 : else
1200 : {
1201 44 : nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
1202 44 : fCreditCached = true;
1203 44 : credit += nCreditCached;
1204 : }
1205 : }
1206 44 : if (filter & ISMINE_WATCH_ONLY)
1207 : {
1208 1 : if (fWatchCreditCached)
1209 0 : credit += nWatchCreditCached;
1210 : else
1211 : {
1212 1 : nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
1213 1 : fWatchCreditCached = true;
1214 1 : credit += nWatchCreditCached;
1215 : }
1216 : }
1217 44 : return credit;
1218 : }
1219 :
1220 4 : CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
1221 : {
1222 5 : if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1223 : {
1224 1 : if (fUseCache && fImmatureCreditCached)
1225 0 : return nImmatureCreditCached;
1226 1 : nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
1227 1 : fImmatureCreditCached = true;
1228 1 : return nImmatureCreditCached;
1229 : }
1230 :
1231 : return 0;
1232 : }
1233 :
1234 11684 : CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
1235 : {
1236 11684 : if (pwallet == 0)
1237 : return 0;
1238 :
1239 : // Must wait until coinbase is safely deep enough in the chain before valuing it
1240 11684 : if (IsCoinBase() && GetBlocksToMaturity() > 0)
1241 : return 0;
1242 :
1243 4701 : if (fUseCache && fAvailableCreditCached)
1244 3234 : return nAvailableCreditCached;
1245 :
1246 1467 : CAmount nCredit = 0;
1247 1467 : uint256 hashTx = GetHash();
1248 7186 : for (unsigned int i = 0; i < vout.size(); i++)
1249 : {
1250 2126 : if (!pwallet->IsSpent(hashTx, i))
1251 : {
1252 2864 : const CTxOut &txout = vout[i];
1253 1432 : nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
1254 2864 : if (!MoneyRange(nCredit))
1255 0 : throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
1256 : }
1257 : }
1258 :
1259 1467 : nAvailableCreditCached = nCredit;
1260 1467 : fAvailableCreditCached = true;
1261 1467 : return nCredit;
1262 : }
1263 :
1264 0 : CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
1265 : {
1266 0 : if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1267 : {
1268 0 : if (fUseCache && fImmatureWatchCreditCached)
1269 0 : return nImmatureWatchCreditCached;
1270 0 : nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
1271 0 : fImmatureWatchCreditCached = true;
1272 0 : return nImmatureWatchCreditCached;
1273 : }
1274 :
1275 : return 0;
1276 : }
1277 :
1278 0 : CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
1279 : {
1280 0 : if (pwallet == 0)
1281 : return 0;
1282 :
1283 : // Must wait until coinbase is safely deep enough in the chain before valuing it
1284 0 : if (IsCoinBase() && GetBlocksToMaturity() > 0)
1285 : return 0;
1286 :
1287 0 : if (fUseCache && fAvailableWatchCreditCached)
1288 0 : return nAvailableWatchCreditCached;
1289 :
1290 : CAmount nCredit = 0;
1291 0 : for (unsigned int i = 0; i < vout.size(); i++)
1292 : {
1293 0 : if (!pwallet->IsSpent(GetHash(), i))
1294 : {
1295 0 : const CTxOut &txout = vout[i];
1296 0 : nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
1297 0 : if (!MoneyRange(nCredit))
1298 0 : throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
1299 : }
1300 : }
1301 :
1302 0 : nAvailableWatchCreditCached = nCredit;
1303 0 : fAvailableWatchCreditCached = true;
1304 0 : return nCredit;
1305 : }
1306 :
1307 0 : CAmount CWalletTx::GetChange() const
1308 : {
1309 0 : if (fChangeCached)
1310 0 : return nChangeCached;
1311 0 : nChangeCached = pwallet->GetChange(*this);
1312 0 : fChangeCached = true;
1313 0 : return nChangeCached;
1314 : }
1315 :
1316 34768 : bool CWalletTx::IsTrusted() const
1317 : {
1318 : // Quick answer in most cases
1319 34768 : if (!CheckFinalTx(*this))
1320 : return false;
1321 69536 : int nDepth = GetDepthInMainChain();
1322 34768 : if (nDepth >= 1)
1323 : return true;
1324 1507 : if (nDepth < 0)
1325 : return false;
1326 3006 : if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
1327 : return false;
1328 :
1329 : // Trusted if all inputs are from us and are in the mempool:
1330 19913 : BOOST_FOREACH(const CTxIn& txin, vin)
1331 : {
1332 : // Transactions not sent by us: not trusted
1333 2093 : const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
1334 2093 : if (parent == NULL)
1335 0 : return false;
1336 4186 : const CTxOut& parentOut = parent->vout[txin.prevout.n];
1337 4186 : if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
1338 : return false;
1339 : }
1340 1471 : return true;
1341 : }
1342 :
1343 6 : bool CWalletTx::IsEquivalentTo(const CWalletTx& tx) const
1344 : {
1345 6 : CMutableTransaction tx1 = *this;
1346 6 : CMutableTransaction tx2 = tx;
1347 30 : for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript();
1348 46 : for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript();
1349 30 : return CTransaction(tx1) == CTransaction(tx2);
1350 : }
1351 :
1352 169 : std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
1353 : {
1354 : std::vector<uint256> result;
1355 :
1356 169 : LOCK(cs_wallet);
1357 : // Sort them in chronological order
1358 : multimap<unsigned int, CWalletTx*> mapSorted;
1359 25614 : BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1360 : {
1361 4100 : CWalletTx& wtx = item.second;
1362 : // Don't rebroadcast if newer than nTime:
1363 4100 : if (wtx.nTimeReceived > nTime)
1364 : continue;
1365 8100 : mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
1366 : }
1367 25314 : BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
1368 : {
1369 4050 : CWalletTx& wtx = *item.second;
1370 4050 : if (wtx.RelayWalletTransaction())
1371 4 : result.push_back(wtx.GetHash());
1372 : }
1373 169 : return result;
1374 : }
1375 :
1376 55094 : void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
1377 : {
1378 : // Do this infrequently and randomly to avoid giving away
1379 : // that these are our transactions.
1380 55094 : if (GetTime() < nNextResend || !fBroadcastTransactions)
1381 54926 : return;
1382 287 : bool fFirst = (nNextResend == 0);
1383 287 : nNextResend = GetTime() + GetRand(30 * 60);
1384 287 : if (fFirst)
1385 : return;
1386 :
1387 : // Only do it if there's been a new block since last time
1388 221 : if (nBestBlockTime < nLastResend)
1389 : return;
1390 168 : nLastResend = GetTime();
1391 :
1392 : // Rebroadcast unconfirmed txes older than 5 minutes before the last
1393 : // block was found:
1394 168 : std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
1395 168 : if (!relayed.empty())
1396 0 : LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
1397 : }
1398 :
1399 : /** @} */ // end of mapWallet
1400 :
1401 :
1402 :
1403 :
1404 : /** @defgroup Actions
1405 : *
1406 : * @{
1407 : */
1408 :
1409 :
1410 192 : CAmount CWallet::GetBalance() const
1411 : {
1412 192 : CAmount nTotal = 0;
1413 : {
1414 192 : LOCK2(cs_main, cs_wallet);
1415 24162 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1416 : {
1417 11697 : const CWalletTx* pcoin = &(*it).second;
1418 11697 : if (pcoin->IsTrusted())
1419 11684 : nTotal += pcoin->GetAvailableCredit();
1420 : }
1421 : }
1422 :
1423 192 : return nTotal;
1424 : }
1425 :
1426 2 : CAmount CWallet::GetUnconfirmedBalance() const
1427 : {
1428 2 : CAmount nTotal = 0;
1429 : {
1430 2 : LOCK2(cs_main, cs_wallet);
1431 16 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1432 : {
1433 4 : const CWalletTx* pcoin = &(*it).second;
1434 4 : if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
1435 0 : nTotal += pcoin->GetAvailableCredit();
1436 : }
1437 : }
1438 2 : return nTotal;
1439 : }
1440 :
1441 2 : CAmount CWallet::GetImmatureBalance() const
1442 : {
1443 2 : CAmount nTotal = 0;
1444 : {
1445 2 : LOCK2(cs_main, cs_wallet);
1446 16 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1447 : {
1448 4 : const CWalletTx* pcoin = &(*it).second;
1449 4 : nTotal += pcoin->GetImmatureCredit();
1450 : }
1451 : }
1452 2 : return nTotal;
1453 : }
1454 :
1455 0 : CAmount CWallet::GetWatchOnlyBalance() const
1456 : {
1457 0 : CAmount nTotal = 0;
1458 : {
1459 0 : LOCK2(cs_main, cs_wallet);
1460 0 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1461 : {
1462 0 : const CWalletTx* pcoin = &(*it).second;
1463 0 : if (pcoin->IsTrusted())
1464 0 : nTotal += pcoin->GetAvailableWatchOnlyCredit();
1465 : }
1466 : }
1467 :
1468 0 : return nTotal;
1469 : }
1470 :
1471 0 : CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
1472 : {
1473 0 : CAmount nTotal = 0;
1474 : {
1475 0 : LOCK2(cs_main, cs_wallet);
1476 0 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1477 : {
1478 0 : const CWalletTx* pcoin = &(*it).second;
1479 0 : if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
1480 0 : nTotal += pcoin->GetAvailableWatchOnlyCredit();
1481 : }
1482 : }
1483 0 : return nTotal;
1484 : }
1485 :
1486 0 : CAmount CWallet::GetImmatureWatchOnlyBalance() const
1487 : {
1488 0 : CAmount nTotal = 0;
1489 : {
1490 0 : LOCK2(cs_main, cs_wallet);
1491 0 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1492 : {
1493 0 : const CWalletTx* pcoin = &(*it).second;
1494 0 : nTotal += pcoin->GetImmatureWatchOnlyCredit();
1495 : }
1496 : }
1497 0 : return nTotal;
1498 : }
1499 :
1500 : /**
1501 : * populate vCoins with vector of available COutputs.
1502 : */
1503 349 : void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const
1504 : {
1505 : vCoins.clear();
1506 :
1507 : {
1508 349 : LOCK2(cs_main, cs_wallet);
1509 48234 : for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1510 : {
1511 23419 : const uint256& wtxid = it->first;
1512 23419 : const CWalletTx* pcoin = &(*it).second;
1513 :
1514 23419 : if (!CheckFinalTx(*pcoin))
1515 : continue;
1516 :
1517 23419 : if (fOnlyConfirmed && !pcoin->IsTrusted())
1518 : continue;
1519 :
1520 23396 : if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1521 : continue;
1522 :
1523 18148 : int nDepth = pcoin->GetDepthInMainChain();
1524 9074 : if (nDepth < 0)
1525 : continue;
1526 :
1527 37466 : for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1528 42588 : isminetype mine = IsMine(pcoin->vout[i]);
1529 40799 : if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
1530 28773 : !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
1531 417 : (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i)))
1532 : vCoins.push_back(COutput(pcoin, i, nDepth,
1533 4847 : ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
1534 4852 : (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO)));
1535 : }
1536 : }
1537 : }
1538 349 : }
1539 :
1540 2271 : static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
1541 : vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
1542 : {
1543 : vector<char> vfIncluded;
1544 :
1545 6813 : vfBest.assign(vValue.size(), true);
1546 2271 : nBest = nTotalLower;
1547 :
1548 2271 : seed_insecure_rand();
1549 :
1550 1268015 : for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1551 : {
1552 3804045 : vfIncluded.assign(vValue.size(), false);
1553 1268015 : CAmount nTotal = 0;
1554 1268015 : bool fReachedTarget = false;
1555 3443888 : for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1556 : {
1557 19416107 : for (unsigned int i = 0; i < vValue.size(); i++)
1558 : {
1559 : //The solver here uses a randomized algorithm,
1560 : //the randomness serves no real security purpose but is just
1561 : //needed to prevent degenerate behavior and it is important
1562 : //that the rng is fast. We do not use a constant random sequence,
1563 : //because there may be some privacy improvement by making
1564 : //the selection random.
1565 12258828 : if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
1566 : {
1567 9332706 : nTotal += vValue[i].first;
1568 9332706 : vfIncluded[i] = true;
1569 4666353 : if (nTotal >= nTargetValue)
1570 : {
1571 1722655 : fReachedTarget = true;
1572 1722655 : if (nTotal < nBest)
1573 : {
1574 3811 : nBest = nTotal;
1575 3811 : vfBest = vfIncluded;
1576 : }
1577 3445310 : nTotal -= vValue[i].first;
1578 3445310 : vfIncluded[i] = false;
1579 : }
1580 : }
1581 : }
1582 : }
1583 : }
1584 2271 : }
1585 :
1586 5545 : bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
1587 : set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
1588 : {
1589 : setCoinsRet.clear();
1590 5545 : nValueRet = 0;
1591 :
1592 : // List of values less than target
1593 : pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1594 5545 : coinLowestLarger.first = std::numeric_limits<CAmount>::max();
1595 5545 : coinLowestLarger.second.first = NULL;
1596 : vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
1597 5545 : CAmount nTotalLower = 0;
1598 :
1599 5545 : random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1600 :
1601 910395 : BOOST_FOREACH(const COutput &output, vCoins)
1602 : {
1603 146743 : if (!output.fSpendable)
1604 2595 : continue;
1605 :
1606 146743 : const CWalletTx *pcoin = output.tx;
1607 :
1608 293486 : if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
1609 : continue;
1610 :
1611 144148 : int i = output.i;
1612 288296 : CAmount n = pcoin->vout[i].nValue;
1613 :
1614 : pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1615 :
1616 144148 : if (n == nTargetValue)
1617 : {
1618 : setCoinsRet.insert(coin.second);
1619 1111 : nValueRet += coin.first;
1620 1111 : return true;
1621 : }
1622 143037 : else if (n < nTargetValue + CENT)
1623 : {
1624 37861 : vValue.push_back(coin);
1625 37861 : nTotalLower += n;
1626 : }
1627 105176 : else if (n < coinLowestLarger.first)
1628 : {
1629 3322 : coinLowestLarger = coin;
1630 : }
1631 : }
1632 :
1633 4434 : if (nTotalLower == nTargetValue)
1634 : {
1635 4342 : for (unsigned int i = 0; i < vValue.size(); ++i)
1636 : {
1637 3840 : setCoinsRet.insert(vValue[i].second);
1638 3840 : nValueRet += vValue[i].first;
1639 : }
1640 : return true;
1641 : }
1642 :
1643 3932 : if (nTotalLower < nTargetValue)
1644 : {
1645 2290 : if (coinLowestLarger.second.first == NULL)
1646 : return false;
1647 : setCoinsRet.insert(coinLowestLarger.second);
1648 1573 : nValueRet += coinLowestLarger.first;
1649 1573 : return true;
1650 : }
1651 :
1652 : // Solve subset sum by stochastic approximation
1653 3284 : sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
1654 : vector<char> vfBest;
1655 : CAmount nBest;
1656 :
1657 3284 : ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1658 1642 : if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1659 1258 : ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
1660 :
1661 : // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1662 : // or the next bigger coin is closer), return the bigger coin
1663 2558 : if (coinLowestLarger.second.first &&
1664 1331 : ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
1665 : {
1666 : setCoinsRet.insert(coinLowestLarger.second);
1667 306 : nValueRet += coinLowestLarger.first;
1668 : }
1669 : else {
1670 54764 : for (unsigned int i = 0; i < vValue.size(); i++)
1671 53428 : if (vfBest[i])
1672 : {
1673 28094 : setCoinsRet.insert(vValue[i].second);
1674 28094 : nValueRet += vValue[i].first;
1675 : }
1676 :
1677 1336 : LogPrint("selectcoins", "SelectCoins() best subset: ");
1678 54764 : for (unsigned int i = 0; i < vValue.size(); i++)
1679 53428 : if (vfBest[i])
1680 42141 : LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
1681 2672 : LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
1682 : }
1683 :
1684 1642 : return true;
1685 : }
1686 :
1687 336 : bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
1688 : {
1689 : vector<COutput> vCoins;
1690 336 : AvailableCoins(vCoins, true, coinControl);
1691 :
1692 : // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1693 384 : if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
1694 : {
1695 0 : BOOST_FOREACH(const COutput& out, vCoins)
1696 : {
1697 0 : if (!out.fSpendable)
1698 : continue;
1699 0 : nValueRet += out.tx->vout[out.i].nValue;
1700 0 : setCoinsRet.insert(make_pair(out.tx, out.i));
1701 : }
1702 0 : return (nValueRet >= nTargetValue);
1703 : }
1704 :
1705 : // calculate value from preset inputs and store them
1706 : set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
1707 336 : CAmount nValueFromPresetInputs = 0;
1708 :
1709 : std::vector<COutPoint> vPresetInputs;
1710 336 : if (coinControl)
1711 : coinControl->ListSelected(vPresetInputs);
1712 2098 : BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
1713 : {
1714 34 : map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
1715 34 : if (it != mapWallet.end())
1716 : {
1717 16 : const CWalletTx* pcoin = &it->second;
1718 : // Clearly invalid input, fail
1719 32 : if (pcoin->vout.size() <= outpoint.n)
1720 : return false;
1721 32 : nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
1722 32 : setPresetCoins.insert(make_pair(pcoin, outpoint.n));
1723 : } else
1724 : return false; // TODO: Allow non-wallet inputs
1725 : }
1726 :
1727 : // remove preset inputs from vCoins
1728 1551 : for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
1729 : {
1730 88 : if (setPresetCoins.count(make_pair(it->tx, it->i)))
1731 16 : it = vCoins.erase(it);
1732 : else
1733 : ++it;
1734 : }
1735 :
1736 664 : bool res = nTargetValue <= nValueFromPresetInputs ||
1737 1071 : SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1738 864 : SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1739 82 : (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));
1740 :
1741 : // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
1742 : setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
1743 :
1744 : // add preset inputs to the total value selected
1745 335 : nValueRet += nValueFromPresetInputs;
1746 :
1747 335 : return res;
1748 : }
1749 :
1750 22 : bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching)
1751 : {
1752 : vector<CRecipient> vecSend;
1753 :
1754 : // Turn the txout set into a CRecipient vector
1755 287 : BOOST_FOREACH(const CTxOut& txOut, tx.vout)
1756 : {
1757 62 : CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
1758 31 : vecSend.push_back(recipient);
1759 : }
1760 :
1761 22 : CCoinControl coinControl;
1762 22 : coinControl.fAllowOtherInputs = true;
1763 22 : coinControl.fAllowWatchOnly = includeWatching;
1764 180 : BOOST_FOREACH(const CTxIn& txin, tx.vin)
1765 8 : coinControl.Select(txin.prevout);
1766 :
1767 22 : CReserveKey reservekey(this);
1768 44 : CWalletTx wtx;
1769 22 : if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
1770 : return false;
1771 :
1772 20 : if (nChangePosRet != -1)
1773 76 : tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
1774 :
1775 : // Add new txins (keeping original txin scriptSig/order)
1776 484 : BOOST_FOREACH(const CTxIn& txin, wtx.vin)
1777 : {
1778 64 : bool found = false;
1779 2740 : BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
1780 : {
1781 790 : if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
1782 : {
1783 : found = true;
1784 : break;
1785 : }
1786 : }
1787 64 : if (!found)
1788 57 : tx.vin.push_back(txin);
1789 : }
1790 :
1791 42 : return true;
1792 : }
1793 :
1794 146 : bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
1795 : int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
1796 : {
1797 146 : CAmount nValue = 0;
1798 146 : unsigned int nSubtractFeeFromAmount = 0;
1799 1714 : BOOST_FOREACH (const CRecipient& recipient, vecSend)
1800 : {
1801 164 : if (nValue < 0 || recipient.nAmount < 0)
1802 : {
1803 0 : strFailReason = _("Transaction amounts must be positive");
1804 0 : return false;
1805 : }
1806 164 : nValue += recipient.nAmount;
1807 :
1808 164 : if (recipient.fSubtractFeeFromAmount)
1809 4 : nSubtractFeeFromAmount++;
1810 : }
1811 146 : if (vecSend.empty() || nValue < 0)
1812 : {
1813 0 : strFailReason = _("Transaction amounts must be positive");
1814 0 : return false;
1815 : }
1816 :
1817 146 : wtxNew.fTimeReceivedIsTxTime = true;
1818 : wtxNew.BindWallet(this);
1819 146 : CMutableTransaction txNew;
1820 :
1821 : // Discourage fee sniping.
1822 : //
1823 : // However because of a off-by-one-error in previous versions we need to
1824 : // neuter it by setting nLockTime to at least one less than nBestHeight.
1825 : // Secondly currently propagation of transactions created for block heights
1826 : // corresponding to blocks that were just mined may be iffy - transactions
1827 : // aren't re-accepted into the mempool - we additionally neuter the code by
1828 : // going ten blocks back. Doesn't yet do anything for sniping, but does act
1829 : // to shake out wallet bugs like not showing nLockTime'd transactions at
1830 : // all.
1831 292 : txNew.nLockTime = std::max(0, chainActive.Height() - 10);
1832 :
1833 : // Secondly occasionally randomly pick a nLockTime even further back, so
1834 : // that transactions that are delayed after signing for whatever reason,
1835 : // e.g. high-latency mix networks and some CoinJoin implementations, have
1836 : // better privacy.
1837 146 : if (GetRandInt(10) == 0)
1838 32 : txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
1839 :
1840 292 : assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
1841 146 : assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
1842 :
1843 : {
1844 146 : LOCK2(cs_main, cs_wallet);
1845 : {
1846 146 : nFeeRet = 0;
1847 : while (true)
1848 : {
1849 : txNew.vin.clear();
1850 : txNew.vout.clear();
1851 336 : wtxNew.fFromMe = true;
1852 336 : nChangePosRet = -1;
1853 336 : bool fFirst = true;
1854 :
1855 336 : CAmount nValueToSelect = nValue;
1856 336 : if (nSubtractFeeFromAmount == 0)
1857 328 : nValueToSelect += nFeeRet;
1858 336 : double dPriority = 0;
1859 : // vouts to the payees
1860 3565 : BOOST_FOREACH (const CRecipient& recipient, vecSend)
1861 : {
1862 1131 : CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
1863 :
1864 377 : if (recipient.fSubtractFeeFromAmount)
1865 : {
1866 8 : txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
1867 :
1868 8 : if (fFirst) // first receiver pays the remainder not divisible by output count
1869 : {
1870 8 : fFirst = false;
1871 8 : txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
1872 : }
1873 : }
1874 :
1875 377 : if (txout.IsDust(::minRelayTxFee))
1876 : {
1877 0 : if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
1878 : {
1879 0 : if (txout.nValue < 0)
1880 0 : strFailReason = _("The transaction amount is too small to pay the fee");
1881 : else
1882 0 : strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
1883 : }
1884 : else
1885 0 : strFailReason = _("Transaction amount too small");
1886 0 : return false;
1887 : }
1888 377 : txNew.vout.push_back(txout);
1889 : }
1890 :
1891 : // Choose coins to use
1892 : set<pair<const CWalletTx*,unsigned int> > setCoins;
1893 336 : CAmount nValueIn = 0;
1894 336 : if (!SelectCoins(nValueToSelect, setCoins, nValueIn, coinControl))
1895 : {
1896 4 : strFailReason = _("Insufficient funds");
1897 2 : return false;
1898 : }
1899 5834 : BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1900 : {
1901 1532 : CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
1902 : //The coin age after the next block (depth+1) is used instead of the current,
1903 : //reflecting an assumption the user would accept a bit more delay for
1904 : //a chance at a free transaction.
1905 : //But mempool inputs might still be in the mempool, so their age stays 0
1906 1532 : int age = pcoin.first->GetDepthInMainChain();
1907 766 : if (age != 0)
1908 729 : age += 1;
1909 766 : dPriority += (double)nCredit * age;
1910 : }
1911 :
1912 334 : const CAmount nChange = nValueIn - nValueToSelect;
1913 334 : if (nChange > 0)
1914 : {
1915 : // Fill a vout to ourself
1916 : // TODO: pass in scriptChange instead of reservekey so
1917 : // change transaction isn't always pay-to-bitcoin-address
1918 : CScript scriptChange;
1919 :
1920 : // coin control: send change to custom address
1921 352 : if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1922 0 : scriptChange = GetScriptForDestination(coinControl->destChange);
1923 :
1924 : // no coin control: send change to newly generated address
1925 : else
1926 : {
1927 : // Note: We use a new key here to keep it from being obvious which side is the change.
1928 : // The drawback is that by not reusing a previous key, the change may be lost if a
1929 : // backup is restored, if the backup doesn't have the new private key for the change.
1930 : // If we reused the old key, it would be possible to add code to look for and
1931 : // rediscover unknown transactions that were written with keys of ours to recover
1932 : // post-backup change.
1933 :
1934 : // Reserve a new key pair from key pool
1935 : CPubKey vchPubKey;
1936 : bool ret;
1937 313 : ret = reservekey.GetReservedKey(vchPubKey);
1938 313 : assert(ret); // should never fail, as we just unlocked
1939 :
1940 1252 : scriptChange = GetScriptForDestination(vchPubKey.GetID());
1941 : }
1942 :
1943 626 : CTxOut newTxOut(nChange, scriptChange);
1944 :
1945 : // We do not move dust-change to fees, because the sender would end up paying more than requested.
1946 : // This would be against the purpose of the all-inclusive feature.
1947 : // So instead we raise the change and deduct from the recipient.
1948 315 : if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
1949 : {
1950 0 : CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
1951 0 : newTxOut.nValue += nDust; // raise change until no more dust
1952 0 : for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
1953 : {
1954 0 : if (vecSend[i].fSubtractFeeFromAmount)
1955 : {
1956 0 : txNew.vout[i].nValue -= nDust;
1957 0 : if (txNew.vout[i].IsDust(::minRelayTxFee))
1958 : {
1959 0 : strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
1960 0 : return false;
1961 : }
1962 : break;
1963 : }
1964 : }
1965 : }
1966 :
1967 : // Never create dust outputs; if we would, just
1968 : // add the dust to the fee.
1969 313 : if (newTxOut.IsDust(::minRelayTxFee))
1970 : {
1971 1 : nFeeRet += nChange;
1972 : reservekey.ReturnKey();
1973 : }
1974 : else
1975 : {
1976 : // Insert change txn at random position:
1977 624 : nChangePosRet = GetRandInt(txNew.vout.size()+1);
1978 936 : vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
1979 312 : txNew.vout.insert(position, newTxOut);
1980 : }
1981 : }
1982 : else
1983 : reservekey.ReturnKey();
1984 :
1985 : // Fill vin
1986 : //
1987 : // Note how the sequence number is set to max()-1 so that the
1988 : // nLockTime set above actually works.
1989 5834 : BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1990 766 : txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
1991 3830 : std::numeric_limits<unsigned int>::max()-1));
1992 :
1993 : // Sign
1994 334 : int nIn = 0;
1995 334 : CTransaction txNewConst(txNew);
1996 5834 : BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1997 : {
1998 : bool signSuccess;
1999 1532 : const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
2000 1532 : CScript& scriptSigRes = txNew.vin[nIn].scriptSig;
2001 766 : if (sign)
2002 1192 : signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes);
2003 : else
2004 510 : signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes);
2005 :
2006 766 : if (!signSuccess)
2007 : {
2008 0 : strFailReason = _("Signing transaction failed");
2009 : return false;
2010 : }
2011 766 : nIn++;
2012 : }
2013 :
2014 334 : unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
2015 :
2016 : // Remove scriptSigs if we used dummy signatures for fee calculation
2017 334 : if (!sign) {
2018 1126 : BOOST_FOREACH (CTxIn& vin, txNew.vin)
2019 340 : vin.scriptSig = CScript();
2020 : }
2021 :
2022 : // Embed the constructed transaction data in wtxNew.
2023 668 : *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
2024 :
2025 : // Limit size
2026 334 : if (nBytes >= MAX_STANDARD_TX_SIZE)
2027 : {
2028 0 : strFailReason = _("Transaction too large");
2029 0 : return false;
2030 : }
2031 :
2032 334 : dPriority = wtxNew.ComputePriority(dPriority, nBytes);
2033 :
2034 : // Can we complete this as a free transaction?
2035 334 : if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
2036 : {
2037 : // Not enough fee: enough priority?
2038 0 : double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
2039 : // Not enough mempool history to estimate: use hard-coded AllowFree.
2040 0 : if (dPriorityNeeded <= 0 && AllowFree(dPriority))
2041 : break;
2042 :
2043 : // Small enough, and priority high enough, to send for free
2044 0 : if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
2045 : break;
2046 : }
2047 :
2048 334 : CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
2049 :
2050 : // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
2051 : // because we must be at the maximum allowed fee.
2052 334 : if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
2053 : {
2054 0 : strFailReason = _("Transaction too large for fee policy");
2055 0 : return false;
2056 : }
2057 :
2058 334 : if (nFeeRet >= nFeeNeeded)
2059 : break; // Done, enough fee included.
2060 :
2061 : // Include more fee and try again.
2062 190 : nFeeRet = nFeeNeeded;
2063 : continue;
2064 190 : }
2065 : }
2066 : }
2067 :
2068 144 : return true;
2069 : }
2070 :
2071 : /**
2072 : * Call after CreateTransaction unless you want to abort
2073 : */
2074 124 : bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
2075 : {
2076 : {
2077 124 : LOCK2(cs_main, cs_wallet);
2078 248 : LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
2079 : {
2080 : // This is only to keep the database open to defeat the auto-flush for the
2081 : // duration of this scope. This is the only place where this optimization
2082 : // maybe makes sense; please don't do it anywhere else.
2083 248 : CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
2084 :
2085 : // Take key pair from key pool so it won't be used again
2086 : reservekey.KeepKey();
2087 :
2088 : // Add tx to wallet, because if it has change it's also ours,
2089 : // otherwise just for transaction history.
2090 124 : AddToWallet(wtxNew, false, pwalletdb);
2091 :
2092 : // Notify that old coins are spent
2093 : set<CWalletTx*> setCoins;
2094 1880 : BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
2095 : {
2096 210 : CWalletTx &coin = mapWallet[txin.prevout.hash];
2097 : coin.BindWallet(this);
2098 420 : NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
2099 : }
2100 :
2101 124 : if (fFileBacked)
2102 248 : delete pwalletdb;
2103 : }
2104 :
2105 : // Track how many getdata requests our transaction gets
2106 248 : mapRequestCount[wtxNew.GetHash()] = 0;
2107 :
2108 124 : if (fBroadcastTransactions)
2109 : {
2110 : // Broadcast
2111 122 : if (!wtxNew.AcceptToMemoryPool(false))
2112 : {
2113 : // This must not fail. The transaction has already been signed and recorded.
2114 0 : LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
2115 0 : return false;
2116 : }
2117 122 : wtxNew.RelayWalletTransaction();
2118 : }
2119 : }
2120 124 : return true;
2121 : }
2122 :
2123 334 : CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
2124 : {
2125 : // payTxFee is user-set "I want to pay this much"
2126 334 : CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
2127 : // user selected total at least (default=true)
2128 351 : if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
2129 14 : nFeeNeeded = payTxFee.GetFeePerK();
2130 : // User didn't set: use -txconfirmtarget to estimate...
2131 334 : if (nFeeNeeded == 0)
2132 317 : nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
2133 : // ... unless we don't have enough mempool data, in which case fall
2134 : // back to a hard-coded fee
2135 334 : if (nFeeNeeded == 0)
2136 317 : nFeeNeeded = minTxFee.GetFee(nTxBytes);
2137 : // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
2138 334 : if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
2139 317 : nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
2140 : // But always obey the maximum
2141 334 : if (nFeeNeeded > maxTxFee)
2142 0 : nFeeNeeded = maxTxFee;
2143 334 : return nFeeNeeded;
2144 : }
2145 :
2146 :
2147 :
2148 :
2149 119 : DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
2150 : {
2151 119 : if (!fFileBacked)
2152 : return DB_LOAD_OK;
2153 119 : fFirstRunRet = false;
2154 357 : DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
2155 119 : if (nLoadWalletRet == DB_NEED_REWRITE)
2156 : {
2157 0 : if (CDB::Rewrite(strWalletFile, "\x04pool"))
2158 : {
2159 0 : LOCK(cs_wallet);
2160 0 : setKeyPool.clear();
2161 : // Note: can't top-up keypool here, because wallet is locked.
2162 : // User will be prompted to unlock wallet the next operation
2163 : // that requires a new key.
2164 : }
2165 : }
2166 :
2167 119 : if (nLoadWalletRet != DB_LOAD_OK)
2168 : return nLoadWalletRet;
2169 238 : fFirstRunRet = !vchDefaultKey.IsValid();
2170 :
2171 119 : uiInterface.LoadWallet(this);
2172 :
2173 119 : return DB_LOAD_OK;
2174 : }
2175 :
2176 :
2177 1 : DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
2178 : {
2179 1 : if (!fFileBacked)
2180 : return DB_LOAD_OK;
2181 3 : DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
2182 1 : if (nZapWalletTxRet == DB_NEED_REWRITE)
2183 : {
2184 0 : if (CDB::Rewrite(strWalletFile, "\x04pool"))
2185 : {
2186 0 : LOCK(cs_wallet);
2187 0 : setKeyPool.clear();
2188 : // Note: can't top-up keypool here, because wallet is locked.
2189 : // User will be prompted to unlock wallet the next operation
2190 : // that requires a new key.
2191 : }
2192 : }
2193 :
2194 1 : if (nZapWalletTxRet != DB_LOAD_OK)
2195 0 : return nZapWalletTxRet;
2196 :
2197 : return DB_LOAD_OK;
2198 : }
2199 :
2200 :
2201 249 : bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
2202 : {
2203 249 : bool fUpdated = false;
2204 : {
2205 249 : LOCK(cs_wallet); // mapAddressBook
2206 498 : std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
2207 498 : fUpdated = mi != mapAddressBook.end();
2208 249 : mapAddressBook[address].name = strName;
2209 249 : if (!strPurpose.empty()) /* update purpose only if requested */
2210 249 : mapAddressBook[address].purpose = strPurpose;
2211 : }
2212 249 : NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
2213 498 : strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
2214 249 : if (!fFileBacked)
2215 : return false;
2216 1494 : if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
2217 : return false;
2218 1245 : return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
2219 : }
2220 :
2221 0 : bool CWallet::DelAddressBook(const CTxDestination& address)
2222 : {
2223 : {
2224 0 : LOCK(cs_wallet); // mapAddressBook
2225 :
2226 0 : if(fFileBacked)
2227 : {
2228 : // Delete destdata tuples associated with address
2229 0 : std::string strAddress = CBitcoinAddress(address).ToString();
2230 0 : BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
2231 : {
2232 0 : CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
2233 0 : }
2234 : }
2235 0 : mapAddressBook.erase(address);
2236 : }
2237 :
2238 0 : NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
2239 :
2240 0 : if (!fFileBacked)
2241 : return false;
2242 0 : CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
2243 0 : return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
2244 : }
2245 :
2246 37 : bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
2247 : {
2248 37 : if (fFileBacked)
2249 : {
2250 111 : if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
2251 : return false;
2252 : }
2253 37 : vchDefaultKey = vchPubKey;
2254 37 : return true;
2255 : }
2256 :
2257 : /**
2258 : * Mark old keypool keys as used,
2259 : * and generate all new keys
2260 : */
2261 1 : bool CWallet::NewKeyPool()
2262 : {
2263 : {
2264 1 : LOCK(cs_wallet);
2265 1 : CWalletDB walletdb(strWalletFile);
2266 12 : BOOST_FOREACH(int64_t nIndex, setKeyPool)
2267 1 : walletdb.ErasePool(nIndex);
2268 1 : setKeyPool.clear();
2269 :
2270 1 : if (IsLocked())
2271 0 : return false;
2272 :
2273 4 : int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
2274 2 : for (int i = 0; i < nKeys; i++)
2275 : {
2276 1 : int64_t nIndex = i+1;
2277 1 : walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
2278 1 : setKeyPool.insert(nIndex);
2279 : }
2280 1 : LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
2281 : }
2282 1 : return true;
2283 : }
2284 :
2285 816 : bool CWallet::TopUpKeyPool(unsigned int kpSize)
2286 : {
2287 : {
2288 816 : LOCK(cs_wallet);
2289 :
2290 816 : if (IsLocked())
2291 0 : return false;
2292 :
2293 816 : CWalletDB walletdb(strWalletFile);
2294 :
2295 : // Top up key pool
2296 : unsigned int nTargetSize;
2297 816 : if (kpSize > 0)
2298 : nTargetSize = kpSize;
2299 : else
2300 3264 : nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
2301 :
2302 3738 : while (setKeyPool.size() < (nTargetSize + 1))
2303 : {
2304 1053 : int64_t nEnd = 1;
2305 2106 : if (!setKeyPool.empty())
2306 4060 : nEnd = *(--setKeyPool.end()) + 1;
2307 1053 : if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
2308 0 : throw runtime_error("TopUpKeyPool(): writing generated key failed");
2309 1053 : setKeyPool.insert(nEnd);
2310 2106 : LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
2311 : }
2312 : }
2313 816 : return true;
2314 : }
2315 :
2316 637 : void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
2317 : {
2318 637 : nIndex = -1;
2319 637 : keypool.vchPubKey = CPubKey();
2320 : {
2321 637 : LOCK(cs_wallet);
2322 :
2323 637 : if (!IsLocked())
2324 636 : TopUpKeyPool();
2325 :
2326 : // Get the oldest key
2327 1274 : if(setKeyPool.empty())
2328 637 : return;
2329 :
2330 637 : CWalletDB walletdb(strWalletFile);
2331 :
2332 1911 : nIndex = *(setKeyPool.begin());
2333 1274 : setKeyPool.erase(setKeyPool.begin());
2334 637 : if (!walletdb.ReadPool(nIndex, keypool))
2335 0 : throw runtime_error("ReserveKeyFromKeyPool(): read failed");
2336 637 : if (!HaveKey(keypool.vchPubKey.GetID()))
2337 0 : throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
2338 1274 : assert(keypool.vchPubKey.IsValid());
2339 637 : LogPrintf("keypool reserve %d\n", nIndex);
2340 : }
2341 : }
2342 :
2343 615 : void CWallet::KeepKey(int64_t nIndex)
2344 : {
2345 : // Remove from key pool
2346 615 : if (fFileBacked)
2347 : {
2348 615 : CWalletDB walletdb(strWalletFile);
2349 615 : walletdb.ErasePool(nIndex);
2350 : }
2351 615 : LogPrintf("keypool keep %d\n", nIndex);
2352 615 : }
2353 :
2354 22 : void CWallet::ReturnKey(int64_t nIndex)
2355 : {
2356 : // Return to key pool
2357 : {
2358 22 : LOCK(cs_wallet);
2359 22 : setKeyPool.insert(nIndex);
2360 : }
2361 22 : LogPrintf("keypool return %d\n", nIndex);
2362 22 : }
2363 :
2364 219 : bool CWallet::GetKeyFromPool(CPubKey& result)
2365 : {
2366 219 : int64_t nIndex = 0;
2367 : CKeyPool keypool;
2368 : {
2369 219 : LOCK(cs_wallet);
2370 219 : ReserveKeyFromKeyPool(nIndex, keypool);
2371 219 : if (nIndex == -1)
2372 : {
2373 0 : if (IsLocked()) return false;
2374 0 : result = GenerateNewKey();
2375 : return true;
2376 : }
2377 219 : KeepKey(nIndex);
2378 219 : result = keypool.vchPubKey;
2379 : }
2380 219 : return true;
2381 : }
2382 :
2383 2 : int64_t CWallet::GetOldestKeyPoolTime()
2384 : {
2385 2 : int64_t nIndex = 0;
2386 : CKeyPool keypool;
2387 2 : ReserveKeyFromKeyPool(nIndex, keypool);
2388 2 : if (nIndex == -1)
2389 0 : return GetTime();
2390 2 : ReturnKey(nIndex);
2391 2 : return keypool.nTime;
2392 : }
2393 :
2394 1 : std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
2395 : {
2396 : map<CTxDestination, CAmount> balances;
2397 :
2398 : {
2399 1 : LOCK(cs_wallet);
2400 6 : BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2401 : {
2402 0 : CWalletTx *pcoin = &walletEntry.second;
2403 :
2404 0 : if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
2405 : continue;
2406 :
2407 0 : if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
2408 : continue;
2409 :
2410 0 : int nDepth = pcoin->GetDepthInMainChain();
2411 0 : if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
2412 : continue;
2413 :
2414 0 : for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2415 : {
2416 : CTxDestination addr;
2417 0 : if (!IsMine(pcoin->vout[i]))
2418 : continue;
2419 0 : if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
2420 : continue;
2421 :
2422 0 : CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
2423 :
2424 0 : if (!balances.count(addr))
2425 0 : balances[addr] = 0;
2426 0 : balances[addr] += n;
2427 : }
2428 : }
2429 : }
2430 :
2431 1 : return balances;
2432 : }
2433 :
2434 1 : set< set<CTxDestination> > CWallet::GetAddressGroupings()
2435 : {
2436 1 : AssertLockHeld(cs_wallet); // mapWallet
2437 : set< set<CTxDestination> > groupings;
2438 : set<CTxDestination> grouping;
2439 :
2440 6 : BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2441 : {
2442 0 : CWalletTx *pcoin = &walletEntry.second;
2443 :
2444 0 : if (pcoin->vin.size() > 0)
2445 : {
2446 0 : bool any_mine = false;
2447 : // group all input addresses with each other
2448 0 : BOOST_FOREACH(CTxIn txin, pcoin->vin)
2449 : {
2450 : CTxDestination address;
2451 0 : if(!IsMine(txin)) /* If this input isn't mine, ignore it */
2452 : continue;
2453 0 : if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
2454 : continue;
2455 : grouping.insert(address);
2456 0 : any_mine = true;
2457 : }
2458 :
2459 : // group change with input addresses
2460 0 : if (any_mine)
2461 : {
2462 0 : BOOST_FOREACH(CTxOut txout, pcoin->vout)
2463 0 : if (IsChange(txout))
2464 : {
2465 : CTxDestination txoutAddr;
2466 0 : if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
2467 : continue;
2468 : grouping.insert(txoutAddr);
2469 : }
2470 : }
2471 0 : if (grouping.size() > 0)
2472 : {
2473 : groupings.insert(grouping);
2474 : grouping.clear();
2475 : }
2476 : }
2477 :
2478 : // group lone addrs by themselves
2479 0 : for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2480 0 : if (IsMine(pcoin->vout[i]))
2481 : {
2482 : CTxDestination address;
2483 0 : if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
2484 : continue;
2485 : grouping.insert(address);
2486 : groupings.insert(grouping);
2487 : grouping.clear();
2488 : }
2489 : }
2490 :
2491 : set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
2492 : map< CTxDestination, set<CTxDestination>* > setmap; // map addresses to the unique group containing it
2493 6 : BOOST_FOREACH(set<CTxDestination> grouping, groupings)
2494 : {
2495 : // make a set of all the groups hit by this new group
2496 : set< set<CTxDestination>* > hits;
2497 : map< CTxDestination, set<CTxDestination>* >::iterator it;
2498 0 : BOOST_FOREACH(CTxDestination address, grouping)
2499 0 : if ((it = setmap.find(address)) != setmap.end())
2500 0 : hits.insert((*it).second);
2501 :
2502 : // merge all hit groups into a new single group and delete old groups
2503 0 : set<CTxDestination>* merged = new set<CTxDestination>(grouping);
2504 0 : BOOST_FOREACH(set<CTxDestination>* hit, hits)
2505 : {
2506 0 : merged->insert(hit->begin(), hit->end());
2507 : uniqueGroupings.erase(hit);
2508 0 : delete hit;
2509 : }
2510 : uniqueGroupings.insert(merged);
2511 :
2512 : // update setmap
2513 0 : BOOST_FOREACH(CTxDestination element, *merged)
2514 0 : setmap[element] = merged;
2515 : }
2516 :
2517 : set< set<CTxDestination> > ret;
2518 6 : BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
2519 : {
2520 : ret.insert(*uniqueGrouping);
2521 0 : delete uniqueGrouping;
2522 : }
2523 :
2524 1 : return ret;
2525 : }
2526 :
2527 0 : std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
2528 : {
2529 0 : LOCK(cs_wallet);
2530 : set<CTxDestination> result;
2531 0 : BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
2532 : {
2533 0 : const CTxDestination& address = item.first;
2534 0 : const string& strName = item.second.name;
2535 0 : if (strName == strAccount)
2536 : result.insert(address);
2537 : }
2538 0 : return result;
2539 : }
2540 :
2541 588 : bool CReserveKey::GetReservedKey(CPubKey& pubkey)
2542 : {
2543 588 : if (nIndex == -1)
2544 : {
2545 : CKeyPool keypool;
2546 416 : pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
2547 416 : if (nIndex != -1)
2548 416 : vchPubKey = keypool.vchPubKey;
2549 : else {
2550 0 : return false;
2551 : }
2552 : }
2553 1176 : assert(vchPubKey.IsValid());
2554 588 : pubkey = vchPubKey;
2555 588 : return true;
2556 : }
2557 :
2558 1237 : void CReserveKey::KeepKey()
2559 : {
2560 1361 : if (nIndex != -1)
2561 396 : pwallet->KeepKey(nIndex);
2562 1361 : nIndex = -1;
2563 1361 : vchPubKey = CPubKey();
2564 1237 : }
2565 :
2566 147 : void CReserveKey::ReturnKey()
2567 : {
2568 443 : if (nIndex != -1)
2569 20 : pwallet->ReturnKey(nIndex);
2570 443 : nIndex = -1;
2571 443 : vchPubKey = CPubKey();
2572 147 : }
2573 :
2574 3 : void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
2575 : {
2576 : setAddress.clear();
2577 :
2578 3 : CWalletDB walletdb(strWalletFile);
2579 :
2580 3 : LOCK2(cs_main, cs_wallet);
2581 1515 : BOOST_FOREACH(const int64_t& id, setKeyPool)
2582 : {
2583 : CKeyPool keypool;
2584 300 : if (!walletdb.ReadPool(id, keypool))
2585 0 : throw runtime_error("GetAllReserveKeyHashes(): read failed");
2586 300 : assert(keypool.vchPubKey.IsValid());
2587 300 : CKeyID keyID = keypool.vchPubKey.GetID();
2588 300 : if (!HaveKey(keyID))
2589 0 : throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
2590 : setAddress.insert(keyID);
2591 : }
2592 3 : }
2593 :
2594 5440 : void CWallet::UpdatedTransaction(const uint256 &hashTx)
2595 : {
2596 : {
2597 5440 : LOCK(cs_wallet);
2598 : // Only notify UI if this transaction is in this wallet
2599 10880 : map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
2600 10880 : if (mi != mapWallet.end())
2601 1219 : NotifyTransactionChanged(this, hashTx, CT_UPDATED);
2602 : }
2603 5440 : }
2604 :
2605 274 : void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
2606 : {
2607 548 : boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
2608 : CPubKey pubkey;
2609 548 : if (!rKey->GetReservedKey(pubkey))
2610 274 : return;
2611 :
2612 274 : script = rKey;
2613 1370 : script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
2614 : }
2615 :
2616 0 : void CWallet::LockCoin(COutPoint& output)
2617 : {
2618 0 : AssertLockHeld(cs_wallet); // setLockedCoins
2619 0 : setLockedCoins.insert(output);
2620 0 : }
2621 :
2622 0 : void CWallet::UnlockCoin(COutPoint& output)
2623 : {
2624 0 : AssertLockHeld(cs_wallet); // setLockedCoins
2625 0 : setLockedCoins.erase(output);
2626 0 : }
2627 :
2628 0 : void CWallet::UnlockAllCoins()
2629 : {
2630 0 : AssertLockHeld(cs_wallet); // setLockedCoins
2631 0 : setLockedCoins.clear();
2632 0 : }
2633 :
2634 4859 : bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
2635 : {
2636 4859 : AssertLockHeld(cs_wallet); // setLockedCoins
2637 : COutPoint outpt(hash, n);
2638 :
2639 9718 : return (setLockedCoins.count(outpt) > 0);
2640 : }
2641 :
2642 1 : void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
2643 : {
2644 1 : AssertLockHeld(cs_wallet); // setLockedCoins
2645 3 : for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
2646 2 : it != setLockedCoins.end(); it++) {
2647 0 : COutPoint outpt = (*it);
2648 0 : vOutpts.push_back(outpt);
2649 : }
2650 1 : }
2651 :
2652 : /** @} */ // end of Actions
2653 :
2654 0 : class CAffectedKeysVisitor : public boost::static_visitor<void> {
2655 : private:
2656 : const CKeyStore &keystore;
2657 : std::vector<CKeyID> &vKeys;
2658 :
2659 : public:
2660 0 : CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
2661 :
2662 0 : void Process(const CScript &script) {
2663 : txnouttype type;
2664 : std::vector<CTxDestination> vDest;
2665 : int nRequired;
2666 0 : if (ExtractDestinations(script, type, vDest, nRequired)) {
2667 0 : BOOST_FOREACH(const CTxDestination &dest, vDest)
2668 : boost::apply_visitor(*this, dest);
2669 0 : }
2670 0 : }
2671 :
2672 0 : void operator()(const CKeyID &keyId) {
2673 0 : if (keystore.HaveKey(keyId))
2674 0 : vKeys.push_back(keyId);
2675 0 : }
2676 :
2677 0 : void operator()(const CScriptID &scriptId) {
2678 : CScript script;
2679 0 : if (keystore.GetCScript(scriptId, script))
2680 0 : Process(script);
2681 0 : }
2682 :
2683 0 : void operator()(const CNoDestination &none) {}
2684 : };
2685 :
2686 3 : void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
2687 3 : AssertLockHeld(cs_wallet); // mapKeyMetadata
2688 : mapKeyBirth.clear();
2689 :
2690 : // get birth times for keys with metadata
2691 1023 : for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
2692 337 : if (it->second.nCreateTime)
2693 674 : mapKeyBirth[it->first] = it->second.nCreateTime;
2694 :
2695 : // map in which we'll infer heights of other keys
2696 9 : CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
2697 : std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
2698 : std::set<CKeyID> setKeys;
2699 3 : GetKeys(setKeys);
2700 2040 : BOOST_FOREACH(const CKeyID &keyid, setKeys) {
2701 337 : if (mapKeyBirth.count(keyid) == 0)
2702 0 : mapKeyFirstBlock[keyid] = pindexMax;
2703 : }
2704 : setKeys.clear();
2705 :
2706 : // if there are no such keys, we're done
2707 3 : if (mapKeyFirstBlock.empty())
2708 3 : return;
2709 :
2710 : // find first block that affects those keys, if there are any left
2711 : std::vector<CKeyID> vAffected;
2712 0 : for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
2713 : // iterate over all wallet transactions...
2714 0 : const CWalletTx &wtx = (*it).second;
2715 0 : BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
2716 0 : if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
2717 : // ... which are already in a block
2718 0 : int nHeight = blit->second->nHeight;
2719 0 : BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
2720 : // iterate over all their outputs
2721 0 : CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
2722 0 : BOOST_FOREACH(const CKeyID &keyid, vAffected) {
2723 : // ... and all their affected keys
2724 0 : std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
2725 0 : if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
2726 0 : rit->second = blit->second;
2727 : }
2728 : vAffected.clear();
2729 : }
2730 : }
2731 : }
2732 :
2733 : // Extract block timestamps for those keys
2734 0 : for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
2735 0 : mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
2736 : }
2737 :
2738 0 : bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2739 : {
2740 0 : if (boost::get<CNoDestination>(&dest))
2741 : return false;
2742 :
2743 0 : mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2744 0 : if (!fFileBacked)
2745 : return true;
2746 0 : return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
2747 : }
2748 :
2749 0 : bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
2750 : {
2751 0 : if (!mapAddressBook[dest].destdata.erase(key))
2752 : return false;
2753 0 : if (!fFileBacked)
2754 : return true;
2755 0 : return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
2756 : }
2757 :
2758 0 : bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2759 : {
2760 0 : mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2761 0 : return true;
2762 : }
2763 :
2764 0 : bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
2765 : {
2766 0 : std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
2767 0 : if(i != mapAddressBook.end())
2768 : {
2769 0 : CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
2770 0 : if(j != i->second.destdata.end())
2771 : {
2772 0 : if(value)
2773 0 : *value = j->second;
2774 : return true;
2775 : }
2776 : }
2777 : return false;
2778 : }
2779 :
2780 1292 : CKeyPool::CKeyPool()
2781 : {
2782 1292 : nTime = GetTime();
2783 355 : }
2784 :
2785 1054 : CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
2786 : {
2787 1054 : nTime = GetTime();
2788 1054 : vchPubKey = vchPubKeyIn;
2789 1054 : }
2790 :
2791 0 : CWalletKey::CWalletKey(int64_t nExpires)
2792 : {
2793 0 : nTimeCreated = (nExpires ? GetTime() : 0);
2794 0 : nTimeExpires = nExpires;
2795 0 : }
2796 :
2797 3673 : int CMerkleTx::SetMerkleBranch(const CBlock& block)
2798 : {
2799 3673 : AssertLockHeld(cs_main);
2800 3673 : CBlock blockTmp;
2801 :
2802 : // Update the tx's hashBlock
2803 3673 : hashBlock = block.GetHash();
2804 :
2805 : // Locate the transaction
2806 10636 : for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
2807 15954 : if (block.vtx[nIndex] == *(CTransaction*)this)
2808 : break;
2809 3673 : if (nIndex == (int)block.vtx.size())
2810 : {
2811 0 : nIndex = -1;
2812 0 : LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
2813 : return 0;
2814 : }
2815 :
2816 : // Is the tx in a block that's in the main chain
2817 7346 : BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
2818 3673 : if (mi == mapBlockIndex.end())
2819 : return 0;
2820 3673 : const CBlockIndex* pindex = (*mi).second;
2821 7346 : if (!pindex || !chainActive.Contains(pindex))
2822 : return 0;
2823 :
2824 3673 : return chainActive.Height() - pindex->nHeight + 1;
2825 : }
2826 :
2827 85901 : int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
2828 : {
2829 171802 : if (hashBlock.IsNull() || nIndex == -1)
2830 : return 0;
2831 81496 : AssertLockHeld(cs_main);
2832 :
2833 : // Find the block it claims to be in
2834 162992 : BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
2835 81496 : if (mi == mapBlockIndex.end())
2836 : return 0;
2837 81487 : CBlockIndex* pindex = (*mi).second;
2838 162974 : if (!pindex || !chainActive.Contains(pindex))
2839 : return 0;
2840 :
2841 81454 : pindexRet = pindex;
2842 81454 : return chainActive.Height() - pindex->nHeight + 1;
2843 : }
2844 :
2845 85900 : int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
2846 : {
2847 85900 : AssertLockHeld(cs_main);
2848 85900 : int nResult = GetDepthInMainChainINTERNAL(pindexRet);
2849 90347 : if (nResult == 0 && !mempool.exists(GetHash()))
2850 : return -1; // Not in chain, not in mempool
2851 :
2852 85855 : return nResult;
2853 : }
2854 :
2855 29741 : int CMerkleTx::GetBlocksToMaturity() const
2856 : {
2857 29741 : if (!IsCoinBase())
2858 : return 0;
2859 59220 : return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
2860 : }
2861 :
2862 :
2863 136 : bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
2864 : {
2865 : CValidationState state;
2866 136 : return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
2867 288 : }
2868 :
|