You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wallet.cpp 49KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2012 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  5. #include "headers.h"
  6. #include "db.h"
  7. #include "crypter.h"
  8. using namespace std;
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // mapWallet
  12. //
  13. std::vector<unsigned char> CWallet::GenerateNewKey()
  14. {
  15. bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
  16. RandAddSeedPerfmon();
  17. CKey key;
  18. key.MakeNewKey(fCompressed);
  19. // Compressed public keys were introduced in version 0.6.0
  20. if (fCompressed)
  21. SetMinVersion(FEATURE_COMPRPUBKEY);
  22. if (!AddKey(key))
  23. throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
  24. return key.GetPubKey();
  25. }
  26. bool CWallet::AddKey(const CKey& key)
  27. {
  28. if (!CCryptoKeyStore::AddKey(key))
  29. return false;
  30. if (!fFileBacked)
  31. return true;
  32. if (!IsCrypted())
  33. return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey());
  34. return true;
  35. }
  36. bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
  37. {
  38. if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
  39. return false;
  40. if (!fFileBacked)
  41. return true;
  42. CRITICAL_BLOCK(cs_wallet)
  43. {
  44. if (pwalletdbEncryption)
  45. return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
  46. else
  47. return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
  48. }
  49. return false;
  50. }
  51. bool CWallet::AddCScript(const CScript& redeemScript)
  52. {
  53. if (!CCryptoKeyStore::AddCScript(redeemScript))
  54. return false;
  55. if (!fFileBacked)
  56. return true;
  57. return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
  58. }
  59. bool CWallet::Unlock(const SecureString& strWalletPassphrase)
  60. {
  61. if (!IsLocked())
  62. return false;
  63. CCrypter crypter;
  64. CKeyingMaterial vMasterKey;
  65. CRITICAL_BLOCK(cs_wallet)
  66. BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
  67. {
  68. if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  69. return false;
  70. if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
  71. return false;
  72. if (CCryptoKeyStore::Unlock(vMasterKey))
  73. return true;
  74. }
  75. return false;
  76. }
  77. bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
  78. {
  79. bool fWasLocked = IsLocked();
  80. CRITICAL_BLOCK(cs_wallet)
  81. {
  82. Lock();
  83. CCrypter crypter;
  84. CKeyingMaterial vMasterKey;
  85. BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
  86. {
  87. if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  88. return false;
  89. if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
  90. return false;
  91. if (CCryptoKeyStore::Unlock(vMasterKey))
  92. {
  93. int64 nStartTime = GetTimeMillis();
  94. crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
  95. pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
  96. nStartTime = GetTimeMillis();
  97. crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
  98. pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
  99. if (pMasterKey.second.nDeriveIterations < 25000)
  100. pMasterKey.second.nDeriveIterations = 25000;
  101. printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
  102. if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
  103. return false;
  104. if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
  105. return false;
  106. CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
  107. if (fWasLocked)
  108. Lock();
  109. return true;
  110. }
  111. }
  112. }
  113. return false;
  114. }
  115. // This class implements an addrIncoming entry that causes pre-0.4
  116. // clients to crash on startup if reading a private-key-encrypted wallet.
  117. class CCorruptAddress
  118. {
  119. public:
  120. IMPLEMENT_SERIALIZE
  121. (
  122. if (nType & SER_DISK)
  123. READWRITE(nVersion);
  124. )
  125. };
  126. bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
  127. {
  128. if (nWalletVersion >= nVersion)
  129. return true;
  130. // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
  131. if (fExplicit && nVersion > nWalletMaxVersion)
  132. nVersion = FEATURE_LATEST;
  133. nWalletVersion = nVersion;
  134. if (nVersion > nWalletMaxVersion)
  135. nWalletMaxVersion = nVersion;
  136. if (fFileBacked)
  137. {
  138. CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
  139. if (nWalletVersion >= 40000)
  140. {
  141. // Versions prior to 0.4.0 did not support the "minversion" record.
  142. // Use a CCorruptAddress to make them crash instead.
  143. CCorruptAddress corruptAddress;
  144. pwalletdb->WriteSetting("addrIncoming", corruptAddress);
  145. }
  146. if (nWalletVersion > 40000)
  147. pwalletdb->WriteMinVersion(nWalletVersion);
  148. if (!pwalletdbIn)
  149. delete pwalletdb;
  150. }
  151. return true;
  152. }
  153. bool CWallet::SetMaxVersion(int nVersion)
  154. {
  155. // cannot downgrade below current version
  156. if (nWalletVersion > nVersion)
  157. return false;
  158. nWalletMaxVersion = nVersion;
  159. return true;
  160. }
  161. bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
  162. {
  163. if (IsCrypted())
  164. return false;
  165. CKeyingMaterial vMasterKey;
  166. RandAddSeedPerfmon();
  167. vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
  168. RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
  169. CMasterKey kMasterKey;
  170. RandAddSeedPerfmon();
  171. kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
  172. RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
  173. CCrypter crypter;
  174. int64 nStartTime = GetTimeMillis();
  175. crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
  176. kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
  177. nStartTime = GetTimeMillis();
  178. crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
  179. kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
  180. if (kMasterKey.nDeriveIterations < 25000)
  181. kMasterKey.nDeriveIterations = 25000;
  182. printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
  183. if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
  184. return false;
  185. if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
  186. return false;
  187. CRITICAL_BLOCK(cs_wallet)
  188. {
  189. mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
  190. if (fFileBacked)
  191. {
  192. pwalletdbEncryption = new CWalletDB(strWalletFile);
  193. pwalletdbEncryption->TxnBegin();
  194. pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
  195. }
  196. if (!EncryptKeys(vMasterKey))
  197. {
  198. if (fFileBacked)
  199. pwalletdbEncryption->TxnAbort();
  200. exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
  201. }
  202. // Encryption was introduced in version 0.4.0
  203. SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
  204. if (fFileBacked)
  205. {
  206. if (!pwalletdbEncryption->TxnCommit())
  207. exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
  208. delete pwalletdbEncryption;
  209. pwalletdbEncryption = NULL;
  210. }
  211. Lock();
  212. Unlock(strWalletPassphrase);
  213. NewKeyPool();
  214. Lock();
  215. // Need to completely rewrite the wallet file; if we don't, bdb might keep
  216. // bits of the unencrypted private key in slack space in the database file.
  217. CDB::Rewrite(strWalletFile);
  218. }
  219. return true;
  220. }
  221. void CWallet::WalletUpdateSpent(const CTransaction &tx)
  222. {
  223. // Anytime a signature is successfully verified, it's proof the outpoint is spent.
  224. // Update the wallet spent flag if it doesn't know due to wallet.dat being
  225. // restored from backup or the user making copies of wallet.dat.
  226. CRITICAL_BLOCK(cs_wallet)
  227. {
  228. BOOST_FOREACH(const CTxIn& txin, tx.vin)
  229. {
  230. map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
  231. if (mi != mapWallet.end())
  232. {
  233. CWalletTx& wtx = (*mi).second;
  234. if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
  235. {
  236. printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
  237. wtx.MarkSpent(txin.prevout.n);
  238. wtx.WriteToDisk();
  239. vWalletUpdated.push_back(txin.prevout.hash);
  240. }
  241. }
  242. }
  243. }
  244. }
  245. void CWallet::MarkDirty()
  246. {
  247. CRITICAL_BLOCK(cs_wallet)
  248. {
  249. BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
  250. item.second.MarkDirty();
  251. }
  252. }
  253. bool CWallet::AddToWallet(const CWalletTx& wtxIn)
  254. {
  255. uint256 hash = wtxIn.GetHash();
  256. CRITICAL_BLOCK(cs_wallet)
  257. {
  258. // Inserts only if not already there, returns tx inserted or tx found
  259. pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
  260. CWalletTx& wtx = (*ret.first).second;
  261. wtx.BindWallet(this);
  262. bool fInsertedNew = ret.second;
  263. if (fInsertedNew)
  264. wtx.nTimeReceived = GetAdjustedTime();
  265. bool fUpdated = false;
  266. if (!fInsertedNew)
  267. {
  268. // Merge
  269. if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
  270. {
  271. wtx.hashBlock = wtxIn.hashBlock;
  272. fUpdated = true;
  273. }
  274. if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
  275. {
  276. wtx.vMerkleBranch = wtxIn.vMerkleBranch;
  277. wtx.nIndex = wtxIn.nIndex;
  278. fUpdated = true;
  279. }
  280. if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
  281. {
  282. wtx.fFromMe = wtxIn.fFromMe;
  283. fUpdated = true;
  284. }
  285. fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
  286. }
  287. //// debug print
  288. printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
  289. // Write to disk
  290. if (fInsertedNew || fUpdated)
  291. if (!wtx.WriteToDisk())
  292. return false;
  293. #ifndef QT_GUI
  294. // If default receiving address gets used, replace it with a new one
  295. CScript scriptDefaultKey;
  296. scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
  297. BOOST_FOREACH(const CTxOut& txout, wtx.vout)
  298. {
  299. if (txout.scriptPubKey == scriptDefaultKey)
  300. {
  301. std::vector<unsigned char> newDefaultKey;
  302. if (GetKeyFromPool(newDefaultKey, false))
  303. {
  304. SetDefaultKey(newDefaultKey);
  305. SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
  306. }
  307. }
  308. }
  309. #endif
  310. // Notify UI
  311. vWalletUpdated.push_back(hash);
  312. // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
  313. WalletUpdateSpent(wtx);
  314. }
  315. // Refresh UI
  316. MainFrameRepaint();
  317. return true;
  318. }
  319. // Add a transaction to the wallet, or update it.
  320. // pblock is optional, but should be provided if the transaction is known to be in a block.
  321. // If fUpdate is true, existing transactions will be updated.
  322. bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
  323. {
  324. uint256 hash = tx.GetHash();
  325. CRITICAL_BLOCK(cs_wallet)
  326. {
  327. bool fExisted = mapWallet.count(hash);
  328. if (fExisted && !fUpdate) return false;
  329. if (fExisted || IsMine(tx) || IsFromMe(tx))
  330. {
  331. CWalletTx wtx(this,tx);
  332. // Get merkle branch if transaction was found in a block
  333. if (pblock)
  334. wtx.SetMerkleBranch(pblock);
  335. return AddToWallet(wtx);
  336. }
  337. else
  338. WalletUpdateSpent(tx);
  339. }
  340. return false;
  341. }
  342. bool CWallet::EraseFromWallet(uint256 hash)
  343. {
  344. if (!fFileBacked)
  345. return false;
  346. CRITICAL_BLOCK(cs_wallet)
  347. {
  348. if (mapWallet.erase(hash))
  349. CWalletDB(strWalletFile).EraseTx(hash);
  350. }
  351. return true;
  352. }
  353. bool CWallet::IsMine(const CTxIn &txin) const
  354. {
  355. CRITICAL_BLOCK(cs_wallet)
  356. {
  357. map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
  358. if (mi != mapWallet.end())
  359. {
  360. const CWalletTx& prev = (*mi).second;
  361. if (txin.prevout.n < prev.vout.size())
  362. if (IsMine(prev.vout[txin.prevout.n]))
  363. return true;
  364. }
  365. }
  366. return false;
  367. }
  368. int64 CWallet::GetDebit(const CTxIn &txin) const
  369. {
  370. CRITICAL_BLOCK(cs_wallet)
  371. {
  372. map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
  373. if (mi != mapWallet.end())
  374. {
  375. const CWalletTx& prev = (*mi).second;
  376. if (txin.prevout.n < prev.vout.size())
  377. if (IsMine(prev.vout[txin.prevout.n]))
  378. return prev.vout[txin.prevout.n].nValue;
  379. }
  380. }
  381. return 0;
  382. }
  383. bool CWallet::IsChange(const CTxOut& txout) const
  384. {
  385. CBitcoinAddress address;
  386. // TODO: fix handling of 'change' outputs. The assumption is that any
  387. // payment to a TX_PUBKEYHASH that is mine but isn't in the address book
  388. // is change. That assumption is likely to break when we implement multisignature
  389. // wallets that return change back into a multi-signature-protected address;
  390. // a better way of identifying which outputs are 'the send' and which are
  391. // 'the change' will need to be implemented (maybe extend CWalletTx to remember
  392. // which output, if any, was change).
  393. if (ExtractAddress(txout.scriptPubKey, address) && HaveKey(address))
  394. CRITICAL_BLOCK(cs_wallet)
  395. if (!mapAddressBook.count(address))
  396. return true;
  397. return false;
  398. }
  399. int64 CWalletTx::GetTxTime() const
  400. {
  401. return nTimeReceived;
  402. }
  403. int CWalletTx::GetRequestCount() const
  404. {
  405. // Returns -1 if it wasn't being tracked
  406. int nRequests = -1;
  407. CRITICAL_BLOCK(pwallet->cs_wallet)
  408. {
  409. if (IsCoinBase())
  410. {
  411. // Generated block
  412. if (hashBlock != 0)
  413. {
  414. map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
  415. if (mi != pwallet->mapRequestCount.end())
  416. nRequests = (*mi).second;
  417. }
  418. }
  419. else
  420. {
  421. // Did anyone request this transaction?
  422. map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
  423. if (mi != pwallet->mapRequestCount.end())
  424. {
  425. nRequests = (*mi).second;
  426. // How about the block it's in?
  427. if (nRequests == 0 && hashBlock != 0)
  428. {
  429. map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
  430. if (mi != pwallet->mapRequestCount.end())
  431. nRequests = (*mi).second;
  432. else
  433. nRequests = 1; // If it's in someone else's block it must have got out
  434. }
  435. }
  436. }
  437. }
  438. return nRequests;
  439. }
  440. void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, list<pair<CBitcoinAddress, int64> >& listReceived,
  441. list<pair<CBitcoinAddress, int64> >& listSent, int64& nFee, string& strSentAccount) const
  442. {
  443. nGeneratedImmature = nGeneratedMature = nFee = 0;
  444. listReceived.clear();
  445. listSent.clear();
  446. strSentAccount = strFromAccount;
  447. if (IsCoinBase())
  448. {
  449. if (GetBlocksToMaturity() > 0)
  450. nGeneratedImmature = pwallet->GetCredit(*this);
  451. else
  452. nGeneratedMature = GetCredit();
  453. return;
  454. }
  455. // Compute fee:
  456. int64 nDebit = GetDebit();
  457. if (nDebit > 0) // debit>0 means we signed/sent this transaction
  458. {
  459. int64 nValueOut = GetValueOut();
  460. nFee = nDebit - nValueOut;
  461. }
  462. // Sent/received.
  463. BOOST_FOREACH(const CTxOut& txout, vout)
  464. {
  465. CBitcoinAddress address;
  466. vector<unsigned char> vchPubKey;
  467. if (!ExtractAddress(txout.scriptPubKey, address))
  468. {
  469. printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
  470. this->GetHash().ToString().c_str());
  471. address = " unknown ";
  472. }
  473. // Don't report 'change' txouts
  474. if (nDebit > 0 && pwallet->IsChange(txout))
  475. continue;
  476. if (nDebit > 0)
  477. listSent.push_back(make_pair(address, txout.nValue));
  478. if (pwallet->IsMine(txout))
  479. listReceived.push_back(make_pair(address, txout.nValue));
  480. }
  481. }
  482. void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
  483. int64& nSent, int64& nFee) const
  484. {
  485. nGenerated = nReceived = nSent = nFee = 0;
  486. int64 allGeneratedImmature, allGeneratedMature, allFee;
  487. allGeneratedImmature = allGeneratedMature = allFee = 0;
  488. string strSentAccount;
  489. list<pair<CBitcoinAddress, int64> > listReceived;
  490. list<pair<CBitcoinAddress, int64> > listSent;
  491. GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount);
  492. if (strAccount == "")
  493. nGenerated = allGeneratedMature;
  494. if (strAccount == strSentAccount)
  495. {
  496. BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& s, listSent)
  497. nSent += s.second;
  498. nFee = allFee;
  499. }
  500. CRITICAL_BLOCK(pwallet->cs_wallet)
  501. {
  502. BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress,int64)& r, listReceived)
  503. {
  504. if (pwallet->mapAddressBook.count(r.first))
  505. {
  506. map<CBitcoinAddress, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
  507. if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
  508. nReceived += r.second;
  509. }
  510. else if (strAccount.empty())
  511. {
  512. nReceived += r.second;
  513. }
  514. }
  515. }
  516. }
  517. void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
  518. {
  519. vtxPrev.clear();
  520. const int COPY_DEPTH = 3;
  521. if (SetMerkleBranch() < COPY_DEPTH)
  522. {
  523. vector<uint256> vWorkQueue;
  524. BOOST_FOREACH(const CTxIn& txin, vin)
  525. vWorkQueue.push_back(txin.prevout.hash);
  526. // This critsect is OK because txdb is already open
  527. CRITICAL_BLOCK(pwallet->cs_wallet)
  528. {
  529. map<uint256, const CMerkleTx*> mapWalletPrev;
  530. set<uint256> setAlreadyDone;
  531. for (int i = 0; i < vWorkQueue.size(); i++)
  532. {
  533. uint256 hash = vWorkQueue[i];
  534. if (setAlreadyDone.count(hash))
  535. continue;
  536. setAlreadyDone.insert(hash);
  537. CMerkleTx tx;
  538. map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
  539. if (mi != pwallet->mapWallet.end())
  540. {
  541. tx = (*mi).second;
  542. BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
  543. mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
  544. }
  545. else if (mapWalletPrev.count(hash))
  546. {
  547. tx = *mapWalletPrev[hash];
  548. }
  549. else if (!fClient && txdb.ReadDiskTx(hash, tx))
  550. {
  551. ;
  552. }
  553. else
  554. {
  555. printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
  556. continue;
  557. }
  558. int nDepth = tx.SetMerkleBranch();
  559. vtxPrev.push_back(tx);
  560. if (nDepth < COPY_DEPTH)
  561. BOOST_FOREACH(const CTxIn& txin, tx.vin)
  562. vWorkQueue.push_back(txin.prevout.hash);
  563. }
  564. }
  565. }
  566. reverse(vtxPrev.begin(), vtxPrev.end());
  567. }
  568. bool CWalletTx::WriteToDisk()
  569. {
  570. return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
  571. }
  572. // Scan the block chain (starting in pindexStart) for transactions
  573. // from or to us. If fUpdate is true, found transactions that already
  574. // exist in the wallet will be updated.
  575. int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
  576. {
  577. int ret = 0;
  578. CBlockIndex* pindex = pindexStart;
  579. CRITICAL_BLOCK(cs_wallet)
  580. {
  581. while (pindex)
  582. {
  583. CBlock block;
  584. block.ReadFromDisk(pindex, true);
  585. BOOST_FOREACH(CTransaction& tx, block.vtx)
  586. {
  587. if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
  588. ret++;
  589. }
  590. pindex = pindex->pnext;
  591. }
  592. }
  593. return ret;
  594. }
  595. int CWallet::ScanForWalletTransaction(const uint256& hashTx)
  596. {
  597. CTransaction tx;
  598. tx.ReadFromDisk(COutPoint(hashTx, 0));
  599. if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
  600. return 1;
  601. return 0;
  602. }
  603. void CWallet::ReacceptWalletTransactions()
  604. {
  605. CTxDB txdb("r");
  606. bool fRepeat = true;
  607. while (fRepeat) CRITICAL_BLOCK(cs_wallet)
  608. {
  609. fRepeat = false;
  610. vector<CDiskTxPos> vMissingTx;
  611. BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
  612. {
  613. CWalletTx& wtx = item.second;
  614. if (wtx.IsCoinBase() && wtx.IsSpent(0))
  615. continue;
  616. CTxIndex txindex;
  617. bool fUpdated = false;
  618. if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
  619. {
  620. // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
  621. if (txindex.vSpent.size() != wtx.vout.size())
  622. {
  623. printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
  624. continue;
  625. }
  626. for (int i = 0; i < txindex.vSpent.size(); i++)
  627. {
  628. if (wtx.IsSpent(i))
  629. continue;
  630. if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
  631. {
  632. wtx.MarkSpent(i);
  633. fUpdated = true;
  634. vMissingTx.push_back(txindex.vSpent[i]);
  635. }
  636. }
  637. if (fUpdated)
  638. {
  639. printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
  640. wtx.MarkDirty();
  641. wtx.WriteToDisk();
  642. }
  643. }
  644. else
  645. {
  646. // Reaccept any txes of ours that aren't already in a block
  647. if (!wtx.IsCoinBase())
  648. wtx.AcceptWalletTransaction(txdb, false);
  649. }
  650. }
  651. if (!vMissingTx.empty())
  652. {
  653. // TODO: optimize this to scan just part of the block chain?
  654. if (ScanForWalletTransactions(pindexGenesisBlock))
  655. fRepeat = true; // Found missing transactions: re-do Reaccept.
  656. }
  657. }
  658. }
  659. void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
  660. {
  661. BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
  662. {
  663. if (!tx.IsCoinBase())
  664. {
  665. uint256 hash = tx.GetHash();
  666. if (!txdb.ContainsTx(hash))
  667. RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
  668. }
  669. }
  670. if (!IsCoinBase())
  671. {
  672. uint256 hash = GetHash();
  673. if (!txdb.ContainsTx(hash))
  674. {
  675. printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
  676. RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
  677. }
  678. }
  679. }
  680. void CWalletTx::RelayWalletTransaction()
  681. {
  682. CTxDB txdb("r");
  683. RelayWalletTransaction(txdb);
  684. }
  685. void CWallet::ResendWalletTransactions()
  686. {
  687. // Do this infrequently and randomly to avoid giving away
  688. // that these are our transactions.
  689. static int64 nNextTime;
  690. if (GetTime() < nNextTime)
  691. return;
  692. bool fFirst = (nNextTime == 0);
  693. nNextTime = GetTime() + GetRand(30 * 60);
  694. if (fFirst)
  695. return;
  696. // Only do it if there's been a new block since last time
  697. static int64 nLastTime;
  698. if (nTimeBestReceived < nLastTime)
  699. return;
  700. nLastTime = GetTime();
  701. // Rebroadcast any of our txes that aren't in a block yet
  702. printf("ResendWalletTransactions()\n");
  703. CTxDB txdb("r");
  704. CRITICAL_BLOCK(cs_wallet)
  705. {
  706. // Sort them in chronological order
  707. multimap<unsigned int, CWalletTx*> mapSorted;
  708. BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
  709. {
  710. CWalletTx& wtx = item.second;
  711. // Don't rebroadcast until it's had plenty of time that
  712. // it should have gotten in already by now.
  713. if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
  714. mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
  715. }
  716. BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
  717. {
  718. CWalletTx& wtx = *item.second;
  719. wtx.RelayWalletTransaction(txdb);
  720. }
  721. }
  722. }
  723. //////////////////////////////////////////////////////////////////////////////
  724. //
  725. // Actions
  726. //
  727. int64 CWallet::GetBalance() const
  728. {
  729. int64 nTotal = 0;
  730. CRITICAL_BLOCK(cs_wallet)
  731. {
  732. for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  733. {
  734. const CWalletTx* pcoin = &(*it).second;
  735. if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
  736. continue;
  737. nTotal += pcoin->GetAvailableCredit();
  738. }
  739. }
  740. return nTotal;
  741. }
  742. int64 CWallet::GetUnconfirmedBalance() const
  743. {
  744. int64 nTotal = 0;
  745. CRITICAL_BLOCK(cs_wallet)
  746. {
  747. for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  748. {
  749. const CWalletTx* pcoin = &(*it).second;
  750. if (pcoin->IsFinal() && pcoin->IsConfirmed())
  751. continue;
  752. nTotal += pcoin->GetAvailableCredit();
  753. }
  754. }
  755. return nTotal;
  756. }
  757. bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
  758. {
  759. setCoinsRet.clear();
  760. nValueRet = 0;
  761. // List of values less than target
  762. pair<int64, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
  763. coinLowestLarger.first = std::numeric_limits<int64>::max();
  764. coinLowestLarger.second.first = NULL;
  765. vector<pair<int64, pair<const CWalletTx*,unsigned int> > > vValue;
  766. int64 nTotalLower = 0;
  767. CRITICAL_BLOCK(cs_wallet)
  768. {
  769. vector<const CWalletTx*> vCoins;
  770. vCoins.reserve(mapWallet.size());
  771. for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
  772. vCoins.push_back(&(*it).second);
  773. random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
  774. BOOST_FOREACH(const CWalletTx* pcoin, vCoins)
  775. {
  776. if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
  777. continue;
  778. if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
  779. continue;
  780. int nDepth = pcoin->GetDepthInMainChain();
  781. if (nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs))
  782. continue;
  783. for (int i = 0; i < pcoin->vout.size(); i++)
  784. {
  785. if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i]))
  786. continue;
  787. int64 n = pcoin->vout[i].nValue;
  788. if (n <= 0)
  789. continue;
  790. pair<int64,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin,i));
  791. if (n == nTargetValue)
  792. {
  793. setCoinsRet.insert(coin.second);
  794. nValueRet += coin.first;
  795. return true;
  796. }
  797. else if (n < nTargetValue + CENT)
  798. {
  799. vValue.push_back(coin);
  800. nTotalLower += n;
  801. }
  802. else if (n < coinLowestLarger.first)
  803. {
  804. coinLowestLarger = coin;
  805. }
  806. }
  807. }
  808. }
  809. if (nTotalLower == nTargetValue || nTotalLower == nTargetValue + CENT)
  810. {
  811. for (int i = 0; i < vValue.size(); ++i)
  812. {
  813. setCoinsRet.insert(vValue[i].second);
  814. nValueRet += vValue[i].first;
  815. }
  816. return true;
  817. }
  818. if (nTotalLower < nTargetValue + (coinLowestLarger.second.first ? CENT : 0))
  819. {
  820. if (coinLowestLarger.second.first == NULL)
  821. return false;
  822. setCoinsRet.insert(coinLowestLarger.second);
  823. nValueRet += coinLowestLarger.first;
  824. return true;
  825. }
  826. if (nTotalLower >= nTargetValue + CENT)
  827. nTargetValue += CENT;
  828. // Solve subset sum by stochastic approximation
  829. sort(vValue.rbegin(), vValue.rend());
  830. vector<char> vfIncluded;
  831. vector<char> vfBest(vValue.size(), true);
  832. int64 nBest = nTotalLower;
  833. for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
  834. {
  835. vfIncluded.assign(vValue.size(), false);
  836. int64 nTotal = 0;
  837. bool fReachedTarget = false;
  838. for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
  839. {
  840. for (int i = 0; i < vValue.size(); i++)
  841. {
  842. if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
  843. {
  844. nTotal += vValue[i].first;
  845. vfIncluded[i] = true;
  846. if (nTotal >= nTargetValue)
  847. {
  848. fReachedTarget = true;
  849. if (nTotal < nBest)
  850. {
  851. nBest = nTotal;
  852. vfBest = vfIncluded;
  853. }
  854. nTotal -= vValue[i].first;
  855. vfIncluded[i] = false;
  856. }
  857. }
  858. }
  859. }
  860. }
  861. // If the next larger is still closer, return it
  862. if (coinLowestLarger.second.first && coinLowestLarger.first - nTargetValue <= nBest - nTargetValue)
  863. {
  864. setCoinsRet.insert(coinLowestLarger.second);
  865. nValueRet += coinLowestLarger.first;
  866. }
  867. else {
  868. for (int i = 0; i < vValue.size(); i++)
  869. if (vfBest[i])
  870. {
  871. setCoinsRet.insert(vValue[i].second);
  872. nValueRet += vValue[i].first;
  873. }
  874. //// debug print
  875. printf("SelectCoins() best subset: ");
  876. for (int i = 0; i < vValue.size(); i++)
  877. if (vfBest[i])
  878. printf("%s ", FormatMoney(vValue[i].first).c_str());
  879. printf("total %s\n", FormatMoney(nBest).c_str());
  880. }
  881. return true;
  882. }
  883. bool CWallet::SelectCoins(int64 nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
  884. {
  885. return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) ||
  886. SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) ||
  887. SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet));
  888. }
  889. bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
  890. {
  891. int64 nValue = 0;
  892. BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
  893. {
  894. if (nValue < 0)
  895. return false;
  896. nValue += s.second;
  897. }
  898. if (vecSend.empty() || nValue < 0)
  899. return false;
  900. wtxNew.BindWallet(this);
  901. CRITICAL_BLOCK(cs_main)
  902. CRITICAL_BLOCK(cs_wallet)
  903. {
  904. // txdb must be opened before the mapWallet lock
  905. CTxDB txdb("r");
  906. {
  907. nFeeRet = nTransactionFee;
  908. loop
  909. {
  910. wtxNew.vin.clear();
  911. wtxNew.vout.clear();
  912. wtxNew.fFromMe = true;
  913. int64 nTotalValue = nValue + nFeeRet;
  914. double dPriority = 0;
  915. // vouts to the payees
  916. BOOST_FOREACH (const PAIRTYPE(CScript, int64)& s, vecSend)
  917. wtxNew.vout.push_back(CTxOut(s.second, s.first));
  918. // Choose coins to use
  919. set<pair<const CWalletTx*,unsigned int> > setCoins;
  920. int64 nValueIn = 0;
  921. if (!SelectCoins(nTotalValue, setCoins, nValueIn))
  922. return false;
  923. BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
  924. {
  925. int64 nCredit = pcoin.first->vout[pcoin.second].nValue;
  926. dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
  927. }
  928. int64 nChange = nValueIn - nValue - nFeeRet;
  929. // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE
  930. // or until nChange becomes zero
  931. // NOTE: this depends on the exact behaviour of GetMinFee
  932. if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT)
  933. {
  934. int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet);
  935. nChange -= nMoveToFee;
  936. nFeeRet += nMoveToFee;
  937. }
  938. if (nChange > 0)
  939. {
  940. // Note: We use a new key here to keep it from being obvious which side is the change.
  941. // The drawback is that by not reusing a previous key, the change may be lost if a
  942. // backup is restored, if the backup doesn't have the new private key for the change.
  943. // If we reused the old key, it would be possible to add code to look for and
  944. // rediscover unknown transactions that were written with keys of ours to recover
  945. // post-backup change.
  946. // Reserve a new key pair from key pool
  947. vector<unsigned char> vchPubKey = reservekey.GetReservedKey();
  948. // assert(mapKeys.count(vchPubKey));
  949. // Fill a vout to ourself
  950. // TODO: pass in scriptChange instead of reservekey so
  951. // change transaction isn't always pay-to-bitcoin-address
  952. CScript scriptChange;
  953. scriptChange.SetBitcoinAddress(vchPubKey);
  954. // Insert change txn at random position:
  955. vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
  956. wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
  957. }
  958. else
  959. reservekey.ReturnKey();
  960. // Fill vin
  961. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
  962. wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
  963. // Sign
  964. int nIn = 0;
  965. BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
  966. if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
  967. return false;
  968. // Limit size
  969. unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
  970. if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
  971. return false;
  972. dPriority /= nBytes;
  973. // Check that enough fee is included
  974. int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000);
  975. bool fAllowFree = CTransaction::AllowFree(dPriority);
  976. int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND);
  977. if (nFeeRet < max(nPayFee, nMinFee))
  978. {
  979. nFeeRet = max(nPayFee, nMinFee);
  980. continue;
  981. }
  982. // Fill vtxPrev by copying from previous transactions vtxPrev
  983. wtxNew.AddSupportingTransactions(txdb);
  984. wtxNew.fTimeReceivedIsTxTime = true;
  985. break;
  986. }
  987. }
  988. }
  989. return true;
  990. }
  991. bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet)
  992. {
  993. vector< pair<CScript, int64> > vecSend;
  994. vecSend.push_back(make_pair(scriptPubKey, nValue));
  995. return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet);
  996. }
  997. // Call after CreateTransaction unless you want to abort
  998. bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
  999. {
  1000. CRITICAL_BLOCK(cs_main)
  1001. CRITICAL_BLOCK(cs_wallet)
  1002. {
  1003. printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
  1004. {
  1005. // This is only to keep the database open to defeat the auto-flush for the
  1006. // duration of this scope. This is the only place where this optimization
  1007. // maybe makes sense; please don't do it anywhere else.
  1008. CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
  1009. // Take key pair from key pool so it won't be used again
  1010. reservekey.KeepKey();
  1011. // Add tx to wallet, because if it has change it's also ours,
  1012. // otherwise just for transaction history.
  1013. AddToWallet(wtxNew);
  1014. // Mark old coins as spent
  1015. set<CWalletTx*> setCoins;
  1016. BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
  1017. {
  1018. CWalletTx &coin = mapWallet[txin.prevout.hash];
  1019. coin.BindWallet(this);
  1020. coin.MarkSpent(txin.prevout.n);
  1021. coin.WriteToDisk();
  1022. vWalletUpdated.push_back(coin.GetHash());
  1023. }
  1024. if (fFileBacked)
  1025. delete pwalletdb;
  1026. }
  1027. // Track how many getdata requests our transaction gets
  1028. mapRequestCount[wtxNew.GetHash()] = 0;
  1029. // Broadcast
  1030. if (!wtxNew.AcceptToMemoryPool())
  1031. {
  1032. // This must not fail. The transaction has already been signed and recorded.
  1033. printf("CommitTransaction() : Error: Transaction not valid");
  1034. return false;
  1035. }
  1036. wtxNew.RelayWalletTransaction();
  1037. }
  1038. MainFrameRepaint();
  1039. return true;
  1040. }
  1041. string CWallet::SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
  1042. {
  1043. CReserveKey reservekey(this);
  1044. int64 nFeeRequired;
  1045. if (IsLocked())
  1046. {
  1047. string strError = _("Error: Wallet locked, unable to create transaction ");
  1048. printf("SendMoney() : %s", strError.c_str());
  1049. return strError;
  1050. }
  1051. if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
  1052. {
  1053. string strError;
  1054. if (nValue + nFeeRequired > GetBalance())
  1055. strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str());
  1056. else
  1057. strError = _("Error: Transaction creation failed ");
  1058. printf("SendMoney() : %s", strError.c_str());
  1059. return strError;
  1060. }
  1061. if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
  1062. return "ABORTED";
  1063. if (!CommitTransaction(wtxNew, reservekey))
  1064. return _("Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
  1065. MainFrameRepaint();
  1066. return "";
  1067. }
  1068. string CWallet::SendMoneyToBitcoinAddress(const CBitcoinAddress& address, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
  1069. {
  1070. // Check amount
  1071. if (nValue <= 0)
  1072. return _("Invalid amount");
  1073. if (nValue + nTransactionFee > GetBalance())
  1074. return _("Insufficient funds");
  1075. // Parse bitcoin address
  1076. CScript scriptPubKey;
  1077. scriptPubKey.SetBitcoinAddress(address);
  1078. return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
  1079. }
  1080. int CWallet::LoadWallet(bool& fFirstRunRet)
  1081. {
  1082. if (!fFileBacked)
  1083. return false;
  1084. fFirstRunRet = false;
  1085. int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
  1086. if (nLoadWalletRet == DB_NEED_REWRITE)
  1087. {
  1088. if (CDB::Rewrite(strWalletFile, "\x04pool"))
  1089. {
  1090. setKeyPool.clear();
  1091. // Note: can't top-up keypool here, because wallet is locked.
  1092. // User will be prompted to unlock wallet the next operation
  1093. // the requires a new key.
  1094. }
  1095. nLoadWalletRet = DB_NEED_REWRITE;
  1096. }
  1097. if (nLoadWalletRet != DB_LOAD_OK)
  1098. return nLoadWalletRet;
  1099. fFirstRunRet = vchDefaultKey.empty();
  1100. CreateThread(ThreadFlushWalletDB, &strWalletFile);
  1101. return DB_LOAD_OK;
  1102. }
  1103. bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName)
  1104. {
  1105. mapAddressBook[address] = strName;
  1106. if (!fFileBacked)
  1107. return false;
  1108. return CWalletDB(strWalletFile).WriteName(address.ToString(), strName);
  1109. }
  1110. bool CWallet::DelAddressBookName(const CBitcoinAddress& address)
  1111. {
  1112. mapAddressBook.erase(address);
  1113. if (!fFileBacked)
  1114. return false;
  1115. return CWalletDB(strWalletFile).EraseName(address.ToString());
  1116. }
  1117. void CWallet::PrintWallet(const CBlock& block)
  1118. {
  1119. CRITICAL_BLOCK(cs_wallet)
  1120. {
  1121. if (mapWallet.count(block.vtx[0].GetHash()))
  1122. {
  1123. CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
  1124. printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
  1125. }
  1126. }
  1127. printf("\n");
  1128. }
  1129. bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
  1130. {
  1131. CRITICAL_BLOCK(cs_wallet)
  1132. {
  1133. map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
  1134. if (mi != mapWallet.end())
  1135. {
  1136. wtx = (*mi).second;
  1137. return true;
  1138. }
  1139. }
  1140. return false;
  1141. }
  1142. bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey)
  1143. {
  1144. if (fFileBacked)
  1145. {
  1146. if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
  1147. return false;
  1148. }
  1149. vchDefaultKey = vchPubKey;
  1150. return true;
  1151. }
  1152. bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
  1153. {
  1154. if (!pwallet->fFileBacked)
  1155. return false;
  1156. strWalletFileOut = pwallet->strWalletFile;
  1157. return true;
  1158. }
  1159. //
  1160. // Mark old keypool keys as used,
  1161. // and generate all new keys
  1162. //
  1163. bool CWallet::NewKeyPool()
  1164. {
  1165. CRITICAL_BLOCK(cs_wallet)
  1166. {
  1167. CWalletDB walletdb(strWalletFile);
  1168. BOOST_FOREACH(int64 nIndex, setKeyPool)
  1169. walletdb.ErasePool(nIndex);
  1170. setKeyPool.clear();
  1171. if (IsLocked())
  1172. return false;
  1173. int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
  1174. for (int i = 0; i < nKeys; i++)
  1175. {
  1176. int64 nIndex = i+1;
  1177. walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
  1178. setKeyPool.insert(nIndex);
  1179. }
  1180. printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
  1181. }
  1182. return true;
  1183. }
  1184. bool CWallet::TopUpKeyPool()
  1185. {
  1186. CRITICAL_BLOCK(cs_wallet)
  1187. {
  1188. if (IsLocked())
  1189. return false;
  1190. CWalletDB walletdb(strWalletFile);
  1191. // Top up key pool
  1192. int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
  1193. while (setKeyPool.size() < nTargetSize+1)
  1194. {
  1195. int64 nEnd = 1;
  1196. if (!setKeyPool.empty())
  1197. nEnd = *(--setKeyPool.end()) + 1;
  1198. if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
  1199. throw runtime_error("TopUpKeyPool() : writing generated key failed");
  1200. setKeyPool.insert(nEnd);
  1201. printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
  1202. }
  1203. }
  1204. return true;
  1205. }
  1206. void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
  1207. {
  1208. nIndex = -1;
  1209. keypool.vchPubKey.clear();
  1210. CRITICAL_BLOCK(cs_wallet)
  1211. {
  1212. if (!IsLocked())
  1213. TopUpKeyPool();
  1214. // Get the oldest key
  1215. if(setKeyPool.empty())
  1216. return;
  1217. CWalletDB walletdb(strWalletFile);
  1218. nIndex = *(setKeyPool.begin());
  1219. setKeyPool.erase(setKeyPool.begin());
  1220. if (!walletdb.ReadPool(nIndex, keypool))
  1221. throw runtime_error("ReserveKeyFromKeyPool() : read failed");
  1222. if (!HaveKey(Hash160(keypool.vchPubKey)))
  1223. throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
  1224. assert(!keypool.vchPubKey.empty());
  1225. printf("keypool reserve %"PRI64d"\n", nIndex);
  1226. }
  1227. }
  1228. int64 CWallet::AddReserveKey(const CKeyPool& keypool)
  1229. {
  1230. CRITICAL_BLOCK(cs_main)
  1231. CRITICAL_BLOCK(cs_wallet)
  1232. {
  1233. CWalletDB walletdb(strWalletFile);
  1234. int64 nIndex = 1 + *(--setKeyPool.end());
  1235. if (!walletdb.WritePool(nIndex, keypool))
  1236. throw runtime_error("AddReserveKey() : writing added key failed");
  1237. setKeyPool.insert(nIndex);
  1238. return nIndex;
  1239. }
  1240. return -1;
  1241. }
  1242. void CWallet::KeepKey(int64 nIndex)
  1243. {
  1244. // Remove from key pool
  1245. if (fFileBacked)
  1246. {
  1247. CWalletDB walletdb(strWalletFile);
  1248. walletdb.ErasePool(nIndex);
  1249. }
  1250. printf("keypool keep %"PRI64d"\n", nIndex);
  1251. }
  1252. void CWallet::ReturnKey(int64 nIndex)
  1253. {
  1254. // Return to key pool
  1255. CRITICAL_BLOCK(cs_wallet)
  1256. setKeyPool.insert(nIndex);
  1257. printf("keypool return %"PRI64d"\n", nIndex);
  1258. }
  1259. bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
  1260. {
  1261. int64 nIndex = 0;
  1262. CKeyPool keypool;
  1263. CRITICAL_BLOCK(cs_wallet)
  1264. {
  1265. ReserveKeyFromKeyPool(nIndex, keypool);
  1266. if (nIndex == -1)
  1267. {
  1268. if (fAllowReuse && !vchDefaultKey.empty())
  1269. {
  1270. result = vchDefaultKey;
  1271. return true;
  1272. }
  1273. if (IsLocked()) return false;
  1274. result = GenerateNewKey();
  1275. return true;
  1276. }
  1277. KeepKey(nIndex);
  1278. result = keypool.vchPubKey;
  1279. }
  1280. return true;
  1281. }
  1282. int64 CWallet::GetOldestKeyPoolTime()
  1283. {
  1284. int64 nIndex = 0;
  1285. CKeyPool keypool;
  1286. ReserveKeyFromKeyPool(nIndex, keypool);
  1287. if (nIndex == -1)
  1288. return GetTime();
  1289. ReturnKey(nIndex);
  1290. return keypool.nTime;
  1291. }
  1292. vector<unsigned char> CReserveKey::GetReservedKey()
  1293. {
  1294. if (nIndex == -1)
  1295. {
  1296. CKeyPool keypool;
  1297. pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
  1298. if (nIndex != -1)
  1299. vchPubKey = keypool.vchPubKey;
  1300. else
  1301. {
  1302. printf("CReserveKey::GetReservedKey(): Warning: using default key instead of a new key, top up your keypool.");
  1303. vchPubKey = pwallet->vchDefaultKey;
  1304. }
  1305. }
  1306. assert(!vchPubKey.empty());
  1307. return vchPubKey;
  1308. }
  1309. void CReserveKey::KeepKey()
  1310. {
  1311. if (nIndex != -1)
  1312. pwallet->KeepKey(nIndex);
  1313. nIndex = -1;
  1314. vchPubKey.clear();
  1315. }
  1316. void CReserveKey::ReturnKey()
  1317. {
  1318. if (nIndex != -1)
  1319. pwallet->ReturnKey(nIndex);
  1320. nIndex = -1;
  1321. vchPubKey.clear();
  1322. }
  1323. void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
  1324. {
  1325. setAddress.clear();
  1326. CWalletDB walletdb(strWalletFile);
  1327. CRITICAL_BLOCK(cs_main)
  1328. CRITICAL_BLOCK(cs_wallet)
  1329. BOOST_FOREACH(const int64& id, setKeyPool)
  1330. {
  1331. CKeyPool keypool;
  1332. if (!walletdb.ReadPool(id, keypool))
  1333. throw runtime_error("GetAllReserveKeyHashes() : read failed");
  1334. CBitcoinAddress address(keypool.vchPubKey);
  1335. assert(!keypool.vchPubKey.empty());
  1336. if (!HaveKey(address))
  1337. throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
  1338. setAddress.insert(address);
  1339. }
  1340. }