]> Git Repo - VerusCoin.git/blame - main.cpp
propset svn:eol-style native
[VerusCoin.git] / main.cpp
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Distributed under the MIT/X11 software license, see the accompanying
3// file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5#include "headers.h"
6#include "cryptopp/sha.h"
7
8
9
10
11
12//
13// Global state
14//
15
16CCriticalSection cs_main;
17
18map<uint256, CTransaction> mapTransactions;
19CCriticalSection cs_mapTransactions;
20unsigned int nTransactionsUpdated = 0;
21map<COutPoint, CInPoint> mapNextTx;
22
23map<uint256, CBlockIndex*> mapBlockIndex;
24const uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
25CBlockIndex* pindexGenesisBlock = NULL;
26int nBestHeight = -1;
27CBigNum bnBestChainWork = 0;
28CBigNum bnBestInvalidWork = 0;
29uint256 hashBestChain = 0;
30CBlockIndex* pindexBest = NULL;
31int64 nTimeBestReceived = 0;
32
33map<uint256, CBlock*> mapOrphanBlocks;
34multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
35
36map<uint256, CDataStream*> mapOrphanTransactions;
37multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
38
39map<uint256, CWalletTx> mapWallet;
40vector<uint256> vWalletUpdated;
41CCriticalSection cs_mapWallet;
42
43map<vector<unsigned char>, CPrivKey> mapKeys;
44map<uint160, vector<unsigned char> > mapPubKeys;
45CCriticalSection cs_mapKeys;
46CKey keyUser;
47
48map<uint256, int> mapRequestCount;
49CCriticalSection cs_mapRequestCount;
50
51map<string, string> mapAddressBook;
52CCriticalSection cs_mapAddressBook;
53
54vector<unsigned char> vchDefaultKey;
55
56double dHashesPerSec;
57int64 nHPSTimerStart;
58
59// Settings
60int fGenerateBitcoins = false;
61int64 nTransactionFee = 0;
62CAddress addrIncoming;
63int fLimitProcessors = false;
64int nLimitProcessors = 1;
65int fMinimizeToTray = true;
66int fMinimizeOnClose = true;
67
68
69
70
71
72
73//////////////////////////////////////////////////////////////////////////////
74//
75// mapKeys
76//
77
78bool AddKey(const CKey& key)
79{
80 CRITICAL_BLOCK(cs_mapKeys)
81 {
82 mapKeys[key.GetPubKey()] = key.GetPrivKey();
83 mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
84 }
85 return CWalletDB().WriteKey(key.GetPubKey(), key.GetPrivKey());
86}
87
88vector<unsigned char> GenerateNewKey()
89{
90 RandAddSeedPerfmon();
91 CKey key;
92 key.MakeNewKey();
93 if (!AddKey(key))
94 throw runtime_error("GenerateNewKey() : AddKey failed\n");
95 return key.GetPubKey();
96}
97
98
99
100
101//////////////////////////////////////////////////////////////////////////////
102//
103// mapWallet
104//
105
106bool AddToWallet(const CWalletTx& wtxIn)
107{
108 uint256 hash = wtxIn.GetHash();
109 CRITICAL_BLOCK(cs_mapWallet)
110 {
111 // Inserts only if not already there, returns tx inserted or tx found
112 pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
113 CWalletTx& wtx = (*ret.first).second;
114 bool fInsertedNew = ret.second;
115 if (fInsertedNew)
116 wtx.nTimeReceived = GetAdjustedTime();
117
118 bool fUpdated = false;
119 if (!fInsertedNew)
120 {
121 // Merge
122 if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
123 {
124 wtx.hashBlock = wtxIn.hashBlock;
125 fUpdated = true;
126 }
127 if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
128 {
129 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
130 wtx.nIndex = wtxIn.nIndex;
131 fUpdated = true;
132 }
133 if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
134 {
135 wtx.fFromMe = wtxIn.fFromMe;
136 fUpdated = true;
137 }
138 if (wtxIn.fSpent && wtxIn.fSpent != wtx.fSpent)
139 {
140 wtx.fSpent = wtxIn.fSpent;
141 fUpdated = true;
142 }
143 }
144
145 //// debug print
146 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,6).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
147
148 // Write to disk
149 if (fInsertedNew || fUpdated)
150 if (!wtx.WriteToDisk())
151 return false;
152
153 // If default receiving address gets used, replace it with a new one
154 CScript scriptDefaultKey;
155 scriptDefaultKey.SetBitcoinAddress(vchDefaultKey);
156 foreach(const CTxOut& txout, wtx.vout)
157 {
158 if (txout.scriptPubKey == scriptDefaultKey)
159 {
160 CWalletDB walletdb;
161 walletdb.WriteDefaultKey(GenerateNewKey());
162 walletdb.WriteName(PubKeyToAddress(vchDefaultKey), "");
163 }
164 }
165
166 // Notify UI
167 vWalletUpdated.push_back(hash);
168 }
169
170 // Refresh UI
171 MainFrameRepaint();
172 return true;
173}
174
175bool AddToWalletIfMine(const CTransaction& tx, const CBlock* pblock)
176{
177 if (tx.IsMine() || mapWallet.count(tx.GetHash()))
178 {
179 CWalletTx wtx(tx);
180 // Get merkle branch if transaction was found in a block
181 if (pblock)
182 wtx.SetMerkleBranch(pblock);
183 return AddToWallet(wtx);
184 }
185 return true;
186}
187
188bool EraseFromWallet(uint256 hash)
189{
190 CRITICAL_BLOCK(cs_mapWallet)
191 {
192 if (mapWallet.erase(hash))
193 CWalletDB().EraseTx(hash);
194 }
195 return true;
196}
197
198void WalletUpdateSpent(const COutPoint& prevout)
199{
200 // Anytime a signature is successfully verified, it's proof the outpoint is spent.
201 // Update the wallet spent flag if it doesn't know due to wallet.dat being
202 // restored from backup or the user making copies of wallet.dat.
203 CRITICAL_BLOCK(cs_mapWallet)
204 {
205 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
206 if (mi != mapWallet.end())
207 {
208 CWalletTx& wtx = (*mi).second;
209 if (!wtx.fSpent && wtx.vout[prevout.n].IsMine())
210 {
211 printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
212 wtx.fSpent = true;
213 wtx.WriteToDisk();
214 vWalletUpdated.push_back(prevout.hash);
215 }
216 }
217 }
218}
219
220
221
222
223
224
225
226
227//////////////////////////////////////////////////////////////////////////////
228//
229// mapOrphanTransactions
230//
231
232void AddOrphanTx(const CDataStream& vMsg)
233{
234 CTransaction tx;
235 CDataStream(vMsg) >> tx;
236 uint256 hash = tx.GetHash();
237 if (mapOrphanTransactions.count(hash))
238 return;
239 CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
240 foreach(const CTxIn& txin, tx.vin)
241 mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
242}
243
244void EraseOrphanTx(uint256 hash)
245{
246 if (!mapOrphanTransactions.count(hash))
247 return;
248 const CDataStream* pvMsg = mapOrphanTransactions[hash];
249 CTransaction tx;
250 CDataStream(*pvMsg) >> tx;
251 foreach(const CTxIn& txin, tx.vin)
252 {
253 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
254 mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
255 {
256 if ((*mi).second == pvMsg)
257 mapOrphanTransactionsByPrev.erase(mi++);
258 else
259 mi++;
260 }
261 }
262 delete pvMsg;
263 mapOrphanTransactions.erase(hash);
264}
265
266
267
268
269
270
271
272
273//////////////////////////////////////////////////////////////////////////////
274//
275// CTransaction
276//
277
278bool CTxIn::IsMine() const
279{
280 CRITICAL_BLOCK(cs_mapWallet)
281 {
282 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
283 if (mi != mapWallet.end())
284 {
285 const CWalletTx& prev = (*mi).second;
286 if (prevout.n < prev.vout.size())
287 if (prev.vout[prevout.n].IsMine())
288 return true;
289 }
290 }
291 return false;
292}
293
294int64 CTxIn::GetDebit() const
295{
296 CRITICAL_BLOCK(cs_mapWallet)
297 {
298 map<uint256, CWalletTx>::iterator mi = mapWallet.find(prevout.hash);
299 if (mi != mapWallet.end())
300 {
301 const CWalletTx& prev = (*mi).second;
302 if (prevout.n < prev.vout.size())
303 if (prev.vout[prevout.n].IsMine())
304 return prev.vout[prevout.n].nValue;
305 }
306 }
307 return 0;
308}
309
310int64 CWalletTx::GetTxTime() const
311{
312 if (!fTimeReceivedIsTxTime && hashBlock != 0)
313 {
314 // If we did not receive the transaction directly, we rely on the block's
315 // time to figure out when it happened. We use the median over a range
316 // of blocks to try to filter out inaccurate block times.
317 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
318 if (mi != mapBlockIndex.end())
319 {
320 CBlockIndex* pindex = (*mi).second;
321 if (pindex)
322 return pindex->GetMedianTime();
323 }
324 }
325 return nTimeReceived;
326}
327
328int CWalletTx::GetRequestCount() const
329{
330 // Returns -1 if it wasn't being tracked
331 int nRequests = -1;
332 CRITICAL_BLOCK(cs_mapRequestCount)
333 {
334 if (IsCoinBase())
335 {
336 // Generated block
337 if (hashBlock != 0)
338 {
339 map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
340 if (mi != mapRequestCount.end())
341 nRequests = (*mi).second;
342 }
343 }
344 else
345 {
346 // Did anyone request this transaction?
347 map<uint256, int>::iterator mi = mapRequestCount.find(GetHash());
348 if (mi != mapRequestCount.end())
349 {
350 nRequests = (*mi).second;
351
352 // How about the block it's in?
353 if (nRequests == 0 && hashBlock != 0)
354 {
355 map<uint256, int>::iterator mi = mapRequestCount.find(hashBlock);
356 if (mi != mapRequestCount.end())
357 nRequests = (*mi).second;
358 else
359 nRequests = 1; // If it's in someone else's block it must have got out
360 }
361 }
362 }
363 }
364 return nRequests;
365}
366
367
368
369
370int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
371{
372 if (fClient)
373 {
374 if (hashBlock == 0)
375 return 0;
376 }
377 else
378 {
379 CBlock blockTmp;
380 if (pblock == NULL)
381 {
382 // Load the block this tx is in
383 CTxIndex txindex;
384 if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
385 return 0;
386 if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
387 return 0;
388 pblock = &blockTmp;
389 }
390
391 // Update the tx's hashBlock
392 hashBlock = pblock->GetHash();
393
394 // Locate the transaction
395 for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
396 if (pblock->vtx[nIndex] == *(CTransaction*)this)
397 break;
398 if (nIndex == pblock->vtx.size())
399 {
400 vMerkleBranch.clear();
401 nIndex = -1;
402 printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
403 return 0;
404 }
405
406 // Fill in merkle branch
407 vMerkleBranch = pblock->GetMerkleBranch(nIndex);
408 }
409
410 // Is the tx in a block that's in the main chain
411 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
412 if (mi == mapBlockIndex.end())
413 return 0;
414 CBlockIndex* pindex = (*mi).second;
415 if (!pindex || !pindex->IsInMainChain())
416 return 0;
417
418 return pindexBest->nHeight - pindex->nHeight + 1;
419}
420
421
422
423void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
424{
425 vtxPrev.clear();
426
427 const int COPY_DEPTH = 3;
428 if (SetMerkleBranch() < COPY_DEPTH)
429 {
430 vector<uint256> vWorkQueue;
431 foreach(const CTxIn& txin, vin)
432 vWorkQueue.push_back(txin.prevout.hash);
433
434 // This critsect is OK because txdb is already open
435 CRITICAL_BLOCK(cs_mapWallet)
436 {
437 map<uint256, const CMerkleTx*> mapWalletPrev;
438 set<uint256> setAlreadyDone;
439 for (int i = 0; i < vWorkQueue.size(); i++)
440 {
441 uint256 hash = vWorkQueue[i];
442 if (setAlreadyDone.count(hash))
443 continue;
444 setAlreadyDone.insert(hash);
445
446 CMerkleTx tx;
447 if (mapWallet.count(hash))
448 {
449 tx = mapWallet[hash];
450 foreach(const CMerkleTx& txWalletPrev, mapWallet[hash].vtxPrev)
451 mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
452 }
453 else if (mapWalletPrev.count(hash))
454 {
455 tx = *mapWalletPrev[hash];
456 }
457 else if (!fClient && txdb.ReadDiskTx(hash, tx))
458 {
459 ;
460 }
461 else
462 {
463 printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
464 continue;
465 }
466
467 int nDepth = tx.SetMerkleBranch();
468 vtxPrev.push_back(tx);
469
470 if (nDepth < COPY_DEPTH)
471 foreach(const CTxIn& txin, tx.vin)
472 vWorkQueue.push_back(txin.prevout.hash);
473 }
474 }
475 }
476
477 reverse(vtxPrev.begin(), vtxPrev.end());
478}
479
480
481
482
483
484
485
486
487
488
489
490bool CTransaction::AcceptTransaction(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
491{
492 if (pfMissingInputs)
493 *pfMissingInputs = false;
494
495 // Coinbase is only valid in a block, not as a loose transaction
496 if (IsCoinBase())
497 return error("AcceptTransaction() : coinbase as individual tx");
498
499 if (!CheckTransaction())
500 return error("AcceptTransaction() : CheckTransaction failed");
501
502 // To help v0.1.5 clients who would see it as a negative number
503 if ((int64)nLockTime > INT_MAX)
504 return error("AcceptTransaction() : not accepting nLockTime beyond 2038 yet");
505
506 // Do we already have it?
507 uint256 hash = GetHash();
508 CRITICAL_BLOCK(cs_mapTransactions)
509 if (mapTransactions.count(hash))
510 return false;
511 if (fCheckInputs)
512 if (txdb.ContainsTx(hash))
513 return false;
514
515 // Check for conflicts with in-memory transactions
516 CTransaction* ptxOld = NULL;
517 for (int i = 0; i < vin.size(); i++)
518 {
519 COutPoint outpoint = vin[i].prevout;
520 if (mapNextTx.count(outpoint))
521 {
522 // Disable replacement feature for now
523 return false;
524
525 // Allow replacing with a newer version of the same transaction
526 if (i != 0)
527 return false;
528 ptxOld = mapNextTx[outpoint].ptx;
529 if (!IsNewerThan(*ptxOld))
530 return false;
531 for (int i = 0; i < vin.size(); i++)
532 {
533 COutPoint outpoint = vin[i].prevout;
534 if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
535 return false;
536 }
537 break;
538 }
539 }
540
541 // Check against previous transactions
542 map<uint256, CTxIndex> mapUnused;
543 int64 nFees = 0;
544 if (fCheckInputs && !ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false))
545 {
546 if (pfMissingInputs)
547 *pfMissingInputs = true;
548 return error("AcceptTransaction() : ConnectInputs failed %s", hash.ToString().substr(0,6).c_str());
549 }
550
551 // Store transaction in memory
552 CRITICAL_BLOCK(cs_mapTransactions)
553 {
554 if (ptxOld)
555 {
556 printf("AcceptTransaction() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
557 ptxOld->RemoveFromMemoryPool();
558 }
559 AddToMemoryPool();
560 }
561
562 ///// are we sure this is ok when loading transactions or restoring block txes
563 // If updated, erase old tx from wallet
564 if (ptxOld)
565 EraseFromWallet(ptxOld->GetHash());
566
567 printf("AcceptTransaction(): accepted %s\n", hash.ToString().substr(0,6).c_str());
568 return true;
569}
570
571
572bool CTransaction::AddToMemoryPool()
573{
574 // Add to memory pool without checking anything. Don't call this directly,
575 // call AcceptTransaction to properly check the transaction first.
576 CRITICAL_BLOCK(cs_mapTransactions)
577 {
578 uint256 hash = GetHash();
579 mapTransactions[hash] = *this;
580 for (int i = 0; i < vin.size(); i++)
581 mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
582 nTransactionsUpdated++;
583 }
584 return true;
585}
586
587
588bool CTransaction::RemoveFromMemoryPool()
589{
590 // Remove transaction from memory pool
591 CRITICAL_BLOCK(cs_mapTransactions)
592 {
593 foreach(const CTxIn& txin, vin)
594 mapNextTx.erase(txin.prevout);
595 mapTransactions.erase(GetHash());
596 nTransactionsUpdated++;
597 }
598 return true;
599}
600
601
602
603
604
605
606int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
607{
608 if (hashBlock == 0 || nIndex == -1)
609 return 0;
610
611 // Find the block it claims to be in
612 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
613 if (mi == mapBlockIndex.end())
614 return 0;
615 CBlockIndex* pindex = (*mi).second;
616 if (!pindex || !pindex->IsInMainChain())
617 return 0;
618
619 // Make sure the merkle branch connects to this block
620 if (!fMerkleVerified)
621 {
622 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
623 return 0;
624 fMerkleVerified = true;
625 }
626
627 nHeightRet = pindex->nHeight;
628 return pindexBest->nHeight - pindex->nHeight + 1;
629}
630
631
632int CMerkleTx::GetBlocksToMaturity() const
633{
634 if (!IsCoinBase())
635 return 0;
636 return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
637}
638
639
640bool CMerkleTx::AcceptTransaction(CTxDB& txdb, bool fCheckInputs)
641{
642 if (fClient)
643 {
644 if (!IsInMainChain() && !ClientConnectInputs())
645 return false;
646 return CTransaction::AcceptTransaction(txdb, false);
647 }
648 else
649 {
650 return CTransaction::AcceptTransaction(txdb, fCheckInputs);
651 }
652}
653
654
655
656bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
657{
658 CRITICAL_BLOCK(cs_mapTransactions)
659 {
660 foreach(CMerkleTx& tx, vtxPrev)
661 {
662 if (!tx.IsCoinBase())
663 {
664 uint256 hash = tx.GetHash();
665 if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
666 tx.AcceptTransaction(txdb, fCheckInputs);
667 }
668 }
669 if (!IsCoinBase())
670 return AcceptTransaction(txdb, fCheckInputs);
671 }
672 return true;
673}
674
675void ReacceptWalletTransactions()
676{
677 CTxDB txdb("r");
678 CRITICAL_BLOCK(cs_mapWallet)
679 {
680 foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
681 {
682 CWalletTx& wtx = item.second;
683 if (wtx.fSpent && wtx.IsCoinBase())
684 continue;
685
686 CTxIndex txindex;
687 if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
688 {
689 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
690 if (!wtx.fSpent)
691 {
692 if (txindex.vSpent.size() != wtx.vout.size())
693 {
694 printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %d != wtx.vout.size() %d\n", txindex.vSpent.size(), wtx.vout.size());
695 continue;
696 }
697 for (int i = 0; i < txindex.vSpent.size(); i++)
698 {
699 if (!txindex.vSpent[i].IsNull() && wtx.vout[i].IsMine())
700 {
701 printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str());
702 wtx.fSpent = true;
703 wtx.WriteToDisk();
704 break;
705 }
706 }
707 }
708 }
709 else
710 {
711 // Reaccept any txes of ours that aren't already in a block
712 if (!wtx.IsCoinBase())
713 wtx.AcceptWalletTransaction(txdb, false);
714 }
715 }
716 }
717}
718
719
720void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
721{
722 foreach(const CMerkleTx& tx, vtxPrev)
723 {
724 if (!tx.IsCoinBase())
725 {
726 uint256 hash = tx.GetHash();
727 if (!txdb.ContainsTx(hash))
728 RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx);
729 }
730 }
731 if (!IsCoinBase())
732 {
733 uint256 hash = GetHash();
734 if (!txdb.ContainsTx(hash))
735 {
736 printf("Relaying wtx %s\n", hash.ToString().substr(0,6).c_str());
737 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
738 }
739 }
740}
741
742void ResendWalletTransactions()
743{
744 // Do this infrequently and randomly to avoid giving away
745 // that these are our transactions.
746 static int64 nNextTime;
747 if (GetTime() < nNextTime)
748 return;
749 bool fFirst = (nNextTime == 0);
750 nNextTime = GetTime() + GetRand(30 * 60);
751 if (fFirst)
752 return;
753
754 // Only do it if there's been a new block since last time
755 static int64 nLastTime;
756 if (nTimeBestReceived < nLastTime)
757 return;
758 nLastTime = GetTime();
759
760 // Rebroadcast any of our txes that aren't in a block yet
761 printf("ResendWalletTransactions()\n");
762 CTxDB txdb("r");
763 CRITICAL_BLOCK(cs_mapWallet)
764 {
765 // Sort them in chronological order
766 multimap<unsigned int, CWalletTx*> mapSorted;
767 foreach(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
768 {
769 CWalletTx& wtx = item.second;
770 // Don't rebroadcast until it's had plenty of time that
771 // it should have gotten in already by now.
772 if (nTimeBestReceived - (int64)wtx.nTimeReceived > 5 * 60)
773 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
774 }
775 foreach(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
776 {
777 CWalletTx& wtx = *item.second;
778 wtx.RelayWalletTransaction(txdb);
779 }
780 }
781}
782
783
784
785
786
787
788
789
790
791
792//////////////////////////////////////////////////////////////////////////////
793//
794// CBlock and CBlockIndex
795//
796
797bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
798{
799 if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
800 return false;
801 if (GetHash() != pindex->GetBlockHash())
802 return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
803 return true;
804}
805
806uint256 GetOrphanRoot(const CBlock* pblock)
807{
808 // Work back to the first block in the orphan chain
809 while (mapOrphanBlocks.count(pblock->hashPrevBlock))
810 pblock = mapOrphanBlocks[pblock->hashPrevBlock];
811 return pblock->GetHash();
812}
813
814int64 CBlock::GetBlockValue(int nHeight, int64 nFees) const
815{
816 int64 nSubsidy = 50 * COIN;
817
818 // Subsidy is cut in half every 4 years
819 nSubsidy >>= (nHeight / 210000);
820
821 return nSubsidy + nFees;
822}
823
824unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
825{
826 const int64 nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
827 const int64 nTargetSpacing = 10 * 60;
828 const int64 nInterval = nTargetTimespan / nTargetSpacing;
829
830 // Genesis block
831 if (pindexLast == NULL)
832 return bnProofOfWorkLimit.GetCompact();
833
834 // Only change once per interval
835 if ((pindexLast->nHeight+1) % nInterval != 0)
836 return pindexLast->nBits;
837
838 // Go back by what we want to be 14 days worth of blocks
839 const CBlockIndex* pindexFirst = pindexLast;
840 for (int i = 0; pindexFirst && i < nInterval-1; i++)
841 pindexFirst = pindexFirst->pprev;
842 assert(pindexFirst);
843
844 // Limit adjustment step
845 int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
846 printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
847 if (nActualTimespan < nTargetTimespan/4)
848 nActualTimespan = nTargetTimespan/4;
849 if (nActualTimespan > nTargetTimespan*4)
850 nActualTimespan = nTargetTimespan*4;
851
852 // Retarget
853 CBigNum bnNew;
854 bnNew.SetCompact(pindexLast->nBits);
855 bnNew *= nActualTimespan;
856 bnNew /= nTargetTimespan;
857
858 if (bnNew > bnProofOfWorkLimit)
859 bnNew = bnProofOfWorkLimit;
860
861 /// debug print
862 printf("GetNextWorkRequired RETARGET\n");
863 printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
864 printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
865 printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
866
867 return bnNew.GetCompact();
868}
869
870bool CheckProofOfWork(uint256 hash, unsigned int nBits)
871{
872 CBigNum bnTarget;
873 bnTarget.SetCompact(nBits);
874
875 // Check range
876 if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
877 return error("CheckProofOfWork() : nBits below minimum work");
878
879 // Check proof of work matches claimed amount
880 if (hash > bnTarget.getuint256())
881 return error("CheckProofOfWork() : hash doesn't match nBits");
882
883 return true;
884}
885
886bool IsInitialBlockDownload()
887{
888 if (pindexBest == NULL)
889 return true;
890 static int64 nLastUpdate;
891 static CBlockIndex* pindexLastBest;
892 if (pindexBest != pindexLastBest)
893 {
894 pindexLastBest = pindexBest;
895 nLastUpdate = GetTime();
896 }
897 return (GetTime() - nLastUpdate < 10 &&
898 pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
899}
900
901void InvalidChainFound(CBlockIndex* pindexNew)
902{
903 if (pindexNew->bnChainWork > bnBestInvalidWork)
904 {
905 bnBestInvalidWork = pindexNew->bnChainWork;
906 CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
907 MainFrameRepaint();
908 }
909 printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
910 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
911 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
912 printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
913}
914
915
916
917
918
919
920
921
922
923
924
925bool CTransaction::DisconnectInputs(CTxDB& txdb)
926{
927 // Relinquish previous transactions' spent pointers
928 if (!IsCoinBase())
929 {
930 foreach(const CTxIn& txin, vin)
931 {
932 COutPoint prevout = txin.prevout;
933
934 // Get prev txindex from disk
935 CTxIndex txindex;
936 if (!txdb.ReadTxIndex(prevout.hash, txindex))
937 return error("DisconnectInputs() : ReadTxIndex failed");
938
939 if (prevout.n >= txindex.vSpent.size())
940 return error("DisconnectInputs() : prevout.n out of range");
941
942 // Mark outpoint as not spent
943 txindex.vSpent[prevout.n].SetNull();
944
945 // Write back
946 txdb.UpdateTxIndex(prevout.hash, txindex);
947 }
948 }
949
950 // Remove transaction from index
951 if (!txdb.EraseTxIndex(*this))
952 return error("DisconnectInputs() : EraseTxPos failed");
953
954 return true;
955}
956
957
958bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
959 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee)
960{
961 // Take over previous transactions' spent pointers
962 if (!IsCoinBase())
963 {
964 int64 nValueIn = 0;
965 for (int i = 0; i < vin.size(); i++)
966 {
967 COutPoint prevout = vin[i].prevout;
968
969 // Read txindex
970 CTxIndex txindex;
971 bool fFound = true;
972 if (fMiner && mapTestPool.count(prevout.hash))
973 {
974 // Get txindex from current proposed changes
975 txindex = mapTestPool[prevout.hash];
976 }
977 else
978 {
979 // Read txindex from txdb
980 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
981 }
982 if (!fFound && (fBlock || fMiner))
983 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
984
985 // Read txPrev
986 CTransaction txPrev;
987 if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
988 {
989 // Get prev tx from single transactions in memory
990 CRITICAL_BLOCK(cs_mapTransactions)
991 {
992 if (!mapTransactions.count(prevout.hash))
993 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
994 txPrev = mapTransactions[prevout.hash];
995 }
996 if (!fFound)
997 txindex.vSpent.resize(txPrev.vout.size());
998 }
999 else
1000 {
1001 // Get prev tx from disk
1002 if (!txPrev.ReadFromDisk(txindex.pos))
1003 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,6).c_str(), prevout.hash.ToString().substr(0,6).c_str());
1004 }
1005
1006 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
1007 return error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,6).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,6).c_str(), txPrev.ToString().c_str());
1008
1009 // If prev is coinbase, check that it's matured
1010 if (txPrev.IsCoinBase())
1011 for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
1012 if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
1013 return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
1014
1015 // Verify signature
1016 if (!VerifySignature(txPrev, *this, i))
1017 return error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,6).c_str());
1018
1019 // Check for conflicts
1020 if (!txindex.vSpent[prevout.n].IsNull())
1021 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,6).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
1022
1023 // Mark outpoints as spent
1024 txindex.vSpent[prevout.n] = posThisTx;
1025
1026 // Write back
1027 if (fBlock)
1028 txdb.UpdateTxIndex(prevout.hash, txindex);
1029 else if (fMiner)
1030 mapTestPool[prevout.hash] = txindex;
1031
1032 nValueIn += txPrev.vout[prevout.n].nValue;
1033
1034 // Check for negative or overflow input values
1035 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
1036 return error("ConnectInputs() : txin values out of range");
1037 }
1038
1039 if (nValueIn < GetValueOut())
1040 return error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,6).c_str());
1041
1042 // Tally transaction fees
1043 int64 nTxFee = nValueIn - GetValueOut();
1044 if (nTxFee < 0)
1045 return error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,6).c_str());
1046 if (nTxFee < nMinFee)
1047 return false;
1048 nFees += nTxFee;
1049 }
1050
1051 if (fBlock)
1052 {
1053 // Add transaction to disk index
1054 if (!txdb.AddTxIndex(*this, posThisTx, pindexBlock->nHeight))
1055 return error("ConnectInputs() : AddTxPos failed");
1056 }
1057 else if (fMiner)
1058 {
1059 // Add transaction to test pool
1060 mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
1061 }
1062
1063 return true;
1064}
1065
1066
1067bool CTransaction::ClientConnectInputs()
1068{
1069 if (IsCoinBase())
1070 return false;
1071
1072 // Take over previous transactions' spent pointers
1073 CRITICAL_BLOCK(cs_mapTransactions)
1074 {
1075 int64 nValueIn = 0;
1076 for (int i = 0; i < vin.size(); i++)
1077 {
1078 // Get prev tx from single transactions in memory
1079 COutPoint prevout = vin[i].prevout;
1080 if (!mapTransactions.count(prevout.hash))
1081 return false;
1082 CTransaction& txPrev = mapTransactions[prevout.hash];
1083
1084 if (prevout.n >= txPrev.vout.size())
1085 return false;
1086
1087 // Verify signature
1088 if (!VerifySignature(txPrev, *this, i))
1089 return error("ConnectInputs() : VerifySignature failed");
1090
1091 ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
1092 ///// this has to go away now that posNext is gone
1093 // // Check for conflicts
1094 // if (!txPrev.vout[prevout.n].posNext.IsNull())
1095 // return error("ConnectInputs() : prev tx already used");
1096 //
1097 // // Flag outpoints as used
1098 // txPrev.vout[prevout.n].posNext = posThisTx;
1099
1100 nValueIn += txPrev.vout[prevout.n].nValue;
1101 }
1102 if (GetValueOut() > nValueIn)
1103 return false;
1104 }
1105
1106 return true;
1107}
1108
1109
1110
1111
1112bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
1113{
1114 // Disconnect in reverse order
1115 for (int i = vtx.size()-1; i >= 0; i--)
1116 if (!vtx[i].DisconnectInputs(txdb))
1117 return false;
1118
1119 // Update block index on disk without changing it in memory.
1120 // The memory index structure will be changed after the db commits.
1121 if (pindex->pprev)
1122 {
1123 CDiskBlockIndex blockindexPrev(pindex->pprev);
1124 blockindexPrev.hashNext = 0;
1125 txdb.WriteBlockIndex(blockindexPrev);
1126 }
1127
1128 return true;
1129}
1130
1131bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
1132{
1133 // Check it again in case a previous version let a bad block in
1134 if (!CheckBlock())
1135 return false;
1136
1137 //// issue here: it doesn't know the version
1138 unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
1139
1140 map<uint256, CTxIndex> mapUnused;
1141 int64 nFees = 0;
1142 foreach(CTransaction& tx, vtx)
1143 {
1144 CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
1145 nTxPos += ::GetSerializeSize(tx, SER_DISK);
1146
1147 if (!tx.ConnectInputs(txdb, mapUnused, posThisTx, pindex, nFees, true, false))
1148 return false;
1149 }
1150
1151 if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
1152 return false;
1153
1154 // Update block index on disk without changing it in memory.
1155 // The memory index structure will be changed after the db commits.
1156 if (pindex->pprev)
1157 {
1158 CDiskBlockIndex blockindexPrev(pindex->pprev);
1159 blockindexPrev.hashNext = pindex->GetBlockHash();
1160 txdb.WriteBlockIndex(blockindexPrev);
1161 }
1162
1163 // Watch for transactions paying to me
1164 foreach(CTransaction& tx, vtx)
1165 AddToWalletIfMine(tx, this);
1166
1167 return true;
1168}
1169
1170
1171
1172bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
1173{
1174 printf("REORGANIZE\n");
1175
1176 // Find the fork
1177 CBlockIndex* pfork = pindexBest;
1178 CBlockIndex* plonger = pindexNew;
1179 while (pfork != plonger)
1180 {
1181 while (plonger->nHeight > pfork->nHeight)
1182 if (!(plonger = plonger->pprev))
1183 return error("Reorganize() : plonger->pprev is null");
1184 if (pfork == plonger)
1185 break;
1186 if (!(pfork = pfork->pprev))
1187 return error("Reorganize() : pfork->pprev is null");
1188 }
1189
1190 // List of what to disconnect
1191 vector<CBlockIndex*> vDisconnect;
1192 for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
1193 vDisconnect.push_back(pindex);
1194
1195 // List of what to connect
1196 vector<CBlockIndex*> vConnect;
1197 for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
1198 vConnect.push_back(pindex);
1199 reverse(vConnect.begin(), vConnect.end());
1200
1201 // Disconnect shorter branch
1202 vector<CTransaction> vResurrect;
1203 foreach(CBlockIndex* pindex, vDisconnect)
1204 {
1205 CBlock block;
1206 if (!block.ReadFromDisk(pindex))
1207 return error("Reorganize() : ReadFromDisk for disconnect failed");
1208 if (!block.DisconnectBlock(txdb, pindex))
1209 return error("Reorganize() : DisconnectBlock failed");
1210
1211 // Queue memory transactions to resurrect
1212 foreach(const CTransaction& tx, block.vtx)
1213 if (!tx.IsCoinBase())
1214 vResurrect.push_back(tx);
1215 }
1216
1217 // Connect longer branch
1218 vector<CTransaction> vDelete;
1219 for (int i = 0; i < vConnect.size(); i++)
1220 {
1221 CBlockIndex* pindex = vConnect[i];
1222 CBlock block;
1223 if (!block.ReadFromDisk(pindex))
1224 return error("Reorganize() : ReadFromDisk for connect failed");
1225 if (!block.ConnectBlock(txdb, pindex))
1226 {
1227 // Invalid block
1228 txdb.TxnAbort();
1229 return error("Reorganize() : ConnectBlock failed");
1230 }
1231
1232 // Queue memory transactions to delete
1233 foreach(const CTransaction& tx, block.vtx)
1234 vDelete.push_back(tx);
1235 }
1236 if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
1237 return error("Reorganize() : WriteHashBestChain failed");
1238
1239 // Commit now because resurrecting could take some time
1240 txdb.TxnCommit();
1241
1242 // Disconnect shorter branch
1243 foreach(CBlockIndex* pindex, vDisconnect)
1244 if (pindex->pprev)
1245 pindex->pprev->pnext = NULL;
1246
1247 // Connect longer branch
1248 foreach(CBlockIndex* pindex, vConnect)
1249 if (pindex->pprev)
1250 pindex->pprev->pnext = pindex;
1251
1252 // Resurrect memory transactions that were in the disconnected branch
1253 foreach(CTransaction& tx, vResurrect)
1254 tx.AcceptTransaction(txdb, false);
1255
1256 // Delete redundant memory transactions that are in the connected branch
1257 foreach(CTransaction& tx, vDelete)
1258 tx.RemoveFromMemoryPool();
1259
1260 return true;
1261}
1262
1263
1264bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
1265{
1266 uint256 hash = GetHash();
1267
1268 txdb.TxnBegin();
1269 if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
1270 {
1271 pindexGenesisBlock = pindexNew;
1272 txdb.WriteHashBestChain(hash);
1273 }
1274 else if (hashPrevBlock == hashBestChain)
1275 {
1276 // Adding to current best branch
1277 if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
1278 {
1279 txdb.TxnAbort();
1280 InvalidChainFound(pindexNew);
1281 return error("SetBestChain() : ConnectBlock failed");
1282 }
1283 txdb.TxnCommit();
1284 pindexNew->pprev->pnext = pindexNew;
1285
1286 // Delete redundant memory transactions
1287 foreach(CTransaction& tx, vtx)
1288 tx.RemoveFromMemoryPool();
1289 }
1290 else
1291 {
1292 // New best branch
1293 if (!Reorganize(txdb, pindexNew))
1294 {
1295 txdb.TxnAbort();
1296 InvalidChainFound(pindexNew);
1297 return error("SetBestChain() : Reorganize failed");
1298 }
1299 }
1300 txdb.TxnCommit();
1301
1302 // New best block
1303 hashBestChain = hash;
1304 pindexBest = pindexNew;
1305 nBestHeight = pindexBest->nHeight;
1306 bnBestChainWork = pindexNew->bnChainWork;
1307 nTimeBestReceived = GetTime();
1308 nTransactionsUpdated++;
1309 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
1310
1311 return true;
1312}
1313
1314
1315bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
1316{
1317 // Check for duplicate
1318 uint256 hash = GetHash();
1319 if (mapBlockIndex.count(hash))
1320 return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
1321
1322 // Construct new block index object
1323 CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
1324 if (!pindexNew)
1325 return error("AddToBlockIndex() : new CBlockIndex failed");
1326 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
1327 pindexNew->phashBlock = &((*mi).first);
1328 map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
1329 if (miPrev != mapBlockIndex.end())
1330 {
1331 pindexNew->pprev = (*miPrev).second;
1332 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
1333 }
1334 pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
1335
1336 CTxDB txdb;
1337 txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
1338
1339 // New best
1340 if (pindexNew->bnChainWork > bnBestChainWork)
1341 if (!SetBestChain(txdb, pindexNew))
1342 return false;
1343
1344 txdb.Close();
1345
1346 if (pindexNew == pindexBest)
1347 {
1348 // Notify UI to display prev block's coinbase if it was ours
1349 static uint256 hashPrevBestCoinBase;
1350 CRITICAL_BLOCK(cs_mapWallet)
1351 vWalletUpdated.push_back(hashPrevBestCoinBase);
1352 hashPrevBestCoinBase = vtx[0].GetHash();
1353 }
1354
1355 MainFrameRepaint();
1356 return true;
1357}
1358
1359
1360
1361
1362bool CBlock::CheckBlock() const
1363{
1364 // These are checks that are independent of context
1365 // that can be verified before saving an orphan block.
1366
1367 // Size limits
1368 if (vtx.empty() || vtx.size() > MAX_SIZE || ::GetSerializeSize(*this, SER_DISK) > MAX_SIZE)
1369 return error("CheckBlock() : size limits failed");
1370
1371 // Check timestamp
1372 if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
1373 return error("CheckBlock() : block timestamp too far in the future");
1374
1375 // First transaction must be coinbase, the rest must not be
1376 if (vtx.empty() || !vtx[0].IsCoinBase())
1377 return error("CheckBlock() : first tx is not coinbase");
1378 for (int i = 1; i < vtx.size(); i++)
1379 if (vtx[i].IsCoinBase())
1380 return error("CheckBlock() : more than one coinbase");
1381
1382 // Check transactions
1383 foreach(const CTransaction& tx, vtx)
1384 if (!tx.CheckTransaction())
1385 return error("CheckBlock() : CheckTransaction failed");
1386
1387 // Check proof of work matches claimed amount
1388 if (!CheckProofOfWork(GetHash(), nBits))
1389 return error("CheckBlock() : proof of work failed");
1390
1391 // Check merkleroot
1392 if (hashMerkleRoot != BuildMerkleTree())
1393 return error("CheckBlock() : hashMerkleRoot mismatch");
1394
1395 return true;
1396}
1397
1398bool CBlock::AcceptBlock()
1399{
1400 // Check for duplicate
1401 uint256 hash = GetHash();
1402 if (mapBlockIndex.count(hash))
1403 return error("AcceptBlock() : block already in mapBlockIndex");
1404
1405 // Get prev block index
1406 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
1407 if (mi == mapBlockIndex.end())
1408 return error("AcceptBlock() : prev block not found");
1409 CBlockIndex* pindexPrev = (*mi).second;
1410
1411 // Check timestamp against prev
1412 if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
1413 return error("AcceptBlock() : block's timestamp is too early");
1414
1415 // Check that all transactions are finalized
1416 foreach(const CTransaction& tx, vtx)
1417 if (!tx.IsFinal(pindexPrev->nHeight+1, GetBlockTime()))
1418 return error("AcceptBlock() : contains a non-final transaction");
1419
1420 // Check proof of work
1421 if (nBits != GetNextWorkRequired(pindexPrev))
1422 return error("AcceptBlock() : incorrect proof of work");
1423
1424 // Check that the block chain matches the known block chain up to a checkpoint
1425 if ((pindexPrev->nHeight+1 == 11111 && hash != uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")) ||
1426 (pindexPrev->nHeight+1 == 33333 && hash != uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")) ||
1427 (pindexPrev->nHeight+1 == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
1428 (pindexPrev->nHeight+1 == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
1429 (pindexPrev->nHeight+1 == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
1430 return error("AcceptBlock() : rejected by checkpoint lockin at %d", pindexPrev->nHeight+1);
1431
1432 // Scanback checkpoint lockin
1433 for (CBlockIndex* pindex = pindexPrev; pindex->nHeight >= 74000; pindex = pindex->pprev)
1434 {
1435 if (pindex->nHeight == 74000 && pindex->GetBlockHash() != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
1436 return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight);
1437 if (pindex->nHeight == 74638 && pindex->GetBlockHash() == uint256("0x0000000000790ab3f22ec756ad43b6ab569abf0bddeb97c67a6f7b1470a7ec1c"))
1438 return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight);
1439 }
1440
1441 // Write block to history file
1442 if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
1443 return error("AcceptBlock() : out of disk space");
1444 unsigned int nFile;
1445 unsigned int nBlockPos;
1446 if (!WriteToDisk(!fClient, nFile, nBlockPos))
1447 return error("AcceptBlock() : WriteToDisk failed");
1448 if (!AddToBlockIndex(nFile, nBlockPos))
1449 return error("AcceptBlock() : AddToBlockIndex failed");
1450
1451 // Relay inventory, but don't relay old inventory during initial block download
1452 if (hashBestChain == hash)
1453 CRITICAL_BLOCK(cs_vNodes)
1454 foreach(CNode* pnode, vNodes)
1455 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 55000))
1456 pnode->PushInventory(CInv(MSG_BLOCK, hash));
1457
1458 return true;
1459}
1460
1461bool ProcessBlock(CNode* pfrom, CBlock* pblock)
1462{
1463 // Check for duplicate
1464 uint256 hash = pblock->GetHash();
1465 if (mapBlockIndex.count(hash))
1466 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
1467 if (mapOrphanBlocks.count(hash))
1468 return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());
1469
1470 // Preliminary checks
1471 if (!pblock->CheckBlock())
1472 {
1473 delete pblock;
1474 return error("ProcessBlock() : CheckBlock FAILED");
1475 }
1476
1477 // If don't already have its previous block, shunt it off to holding area until we get it
1478 if (!mapBlockIndex.count(pblock->hashPrevBlock))
1479 {
1480 printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
1481 mapOrphanBlocks.insert(make_pair(hash, pblock));
1482 mapOrphanBlocksByPrev.insert(make_pair(pblock->hashPrevBlock, pblock));
1483
1484 // Ask this guy to fill in what we're missing
1485 if (pfrom)
1486 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock));
1487 return true;
1488 }
1489
1490 // Store to disk
1491 if (!pblock->AcceptBlock())
1492 {
1493 delete pblock;
1494 return error("ProcessBlock() : AcceptBlock FAILED");
1495 }
1496 delete pblock;
1497
1498 // Recursively process any orphan blocks that depended on this one
1499 vector<uint256> vWorkQueue;
1500 vWorkQueue.push_back(hash);
1501 for (int i = 0; i < vWorkQueue.size(); i++)
1502 {
1503 uint256 hashPrev = vWorkQueue[i];
1504 for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
1505 mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
1506 ++mi)
1507 {
1508 CBlock* pblockOrphan = (*mi).second;
1509 if (pblockOrphan->AcceptBlock())
1510 vWorkQueue.push_back(pblockOrphan->GetHash());
1511 mapOrphanBlocks.erase(pblockOrphan->GetHash());
1512 delete pblockOrphan;
1513 }
1514 mapOrphanBlocksByPrev.erase(hashPrev);
1515 }
1516
1517 printf("ProcessBlock: ACCEPTED\n");
1518 return true;
1519}
1520
1521
1522
1523
1524
1525
1526
1527
1528template<typename Stream>
1529bool ScanMessageStart(Stream& s)
1530{
1531 // Scan ahead to the next pchMessageStart, which should normally be immediately
1532 // at the file pointer. Leaves file pointer at end of pchMessageStart.
1533 s.clear(0);
1534 short prevmask = s.exceptions(0);
1535 const char* p = BEGIN(pchMessageStart);
1536 try
1537 {
1538 loop
1539 {
1540 char c;
1541 s.read(&c, 1);
1542 if (s.fail())
1543 {
1544 s.clear(0);
1545 s.exceptions(prevmask);
1546 return false;
1547 }
1548 if (*p != c)
1549 p = BEGIN(pchMessageStart);
1550 if (*p == c)
1551 {
1552 if (++p == END(pchMessageStart))
1553 {
1554 s.clear(0);
1555 s.exceptions(prevmask);
1556 return true;
1557 }
1558 }
1559 }
1560 }
1561 catch (...)
1562 {
1563 s.clear(0);
1564 s.exceptions(prevmask);
1565 return false;
1566 }
1567}
1568
1569bool CheckDiskSpace(uint64 nAdditionalBytes)
1570{
1571 uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
1572
1573 // Check for 15MB because database could create another 10MB log file at any time
1574 if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
1575 {
1576 fShutdown = true;
1577 string strMessage = _("Warning: Disk space is low ");
1578 strMiscWarning = strMessage;
1579 printf("*** %s\n", strMessage.c_str());
1580 ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
1581 CreateThread(Shutdown, NULL);
1582 return false;
1583 }
1584 return true;
1585}
1586
1587FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
1588{
1589 if (nFile == -1)
1590 return NULL;
1591 FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
1592 if (!file)
1593 return NULL;
1594 if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
1595 {
1596 if (fseek(file, nBlockPos, SEEK_SET) != 0)
1597 {
1598 fclose(file);
1599 return NULL;
1600 }
1601 }
1602 return file;
1603}
1604
1605static unsigned int nCurrentBlockFile = 1;
1606
1607FILE* AppendBlockFile(unsigned int& nFileRet)
1608{
1609 nFileRet = 0;
1610 loop
1611 {
1612 FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
1613 if (!file)
1614 return NULL;
1615 if (fseek(file, 0, SEEK_END) != 0)
1616 return NULL;
1617 // FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
1618 if (ftell(file) < 0x7F000000 - MAX_SIZE)
1619 {
1620 nFileRet = nCurrentBlockFile;
1621 return file;
1622 }
1623 fclose(file);
1624 nCurrentBlockFile++;
1625 }
1626}
1627
1628bool LoadBlockIndex(bool fAllowNew)
1629{
1630 //
1631 // Load block index
1632 //
1633 CTxDB txdb("cr");
1634 if (!txdb.LoadBlockIndex())
1635 return false;
1636 txdb.Close();
1637
1638 //
1639 // Init with genesis block
1640 //
1641 if (mapBlockIndex.empty())
1642 {
1643 if (!fAllowNew)
1644 return false;
1645
1646 // Genesis Block:
1647 // CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
1648 // CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
1649 // CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
1650 // CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
1651 // vMerkleTree: 4a5e1e
1652
1653 // Genesis block
1654 const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
1655 CTransaction txNew;
1656 txNew.vin.resize(1);
1657 txNew.vout.resize(1);
1658 txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
1659 txNew.vout[0].nValue = 50 * COIN;
1660 txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
1661 CBlock block;
1662 block.vtx.push_back(txNew);
1663 block.hashPrevBlock = 0;
1664 block.hashMerkleRoot = block.BuildMerkleTree();
1665 block.nVersion = 1;
1666 block.nTime = 1231006505;
1667 block.nBits = 0x1d00ffff;
1668 block.nNonce = 2083236893;
1669
1670 //// debug print
1671 printf("%s\n", block.GetHash().ToString().c_str());
1672 printf("%s\n", hashGenesisBlock.ToString().c_str());
1673 printf("%s\n", block.hashMerkleRoot.ToString().c_str());
1674 assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
1675 block.print();
1676
1677 assert(block.GetHash() == hashGenesisBlock);
1678
1679 // Start new block file
1680 unsigned int nFile;
1681 unsigned int nBlockPos;
1682 if (!block.WriteToDisk(!fClient, nFile, nBlockPos))
1683 return error("LoadBlockIndex() : writing genesis block to disk failed");
1684 if (!block.AddToBlockIndex(nFile, nBlockPos))
1685 return error("LoadBlockIndex() : genesis block not accepted");
1686 }
1687
1688 return true;
1689}
1690
1691
1692
1693void PrintBlockTree()
1694{
1695 // precompute tree structure
1696 map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
1697 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
1698 {
1699 CBlockIndex* pindex = (*mi).second;
1700 mapNext[pindex->pprev].push_back(pindex);
1701 // test
1702 //while (rand() % 3 == 0)
1703 // mapNext[pindex->pprev].push_back(pindex);
1704 }
1705
1706 vector<pair<int, CBlockIndex*> > vStack;
1707 vStack.push_back(make_pair(0, pindexGenesisBlock));
1708
1709 int nPrevCol = 0;
1710 while (!vStack.empty())
1711 {
1712 int nCol = vStack.back().first;
1713 CBlockIndex* pindex = vStack.back().second;
1714 vStack.pop_back();
1715
1716 // print split or gap
1717 if (nCol > nPrevCol)
1718 {
1719 for (int i = 0; i < nCol-1; i++)
1720 printf("| ");
1721 printf("|\\\n");
1722 }
1723 else if (nCol < nPrevCol)
1724 {
1725 for (int i = 0; i < nCol; i++)
1726 printf("| ");
1727 printf("|\n");
1728 }
1729 nPrevCol = nCol;
1730
1731 // print columns
1732 for (int i = 0; i < nCol; i++)
1733 printf("| ");
1734
1735 // print item
1736 CBlock block;
1737 block.ReadFromDisk(pindex);
1738 printf("%d (%u,%u) %s %s tx %d",
1739 pindex->nHeight,
1740 pindex->nFile,
1741 pindex->nBlockPos,
1742 block.GetHash().ToString().substr(0,20).c_str(),
1743 DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
1744 block.vtx.size());
1745
1746 CRITICAL_BLOCK(cs_mapWallet)
1747 {
1748 if (mapWallet.count(block.vtx[0].GetHash()))
1749 {
1750 CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
1751 printf(" mine: %d %d %d", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit());
1752 }
1753 }
1754 printf("\n");
1755
1756
1757 // put the main timechain first
1758 vector<CBlockIndex*>& vNext = mapNext[pindex];
1759 for (int i = 0; i < vNext.size(); i++)
1760 {
1761 if (vNext[i]->pnext)
1762 {
1763 swap(vNext[0], vNext[i]);
1764 break;
1765 }
1766 }
1767
1768 // iterate children
1769 for (int i = 0; i < vNext.size(); i++)
1770 vStack.push_back(make_pair(nCol+i, vNext[i]));
1771 }
1772}
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783//////////////////////////////////////////////////////////////////////////////
1784//
1785// CAlert
1786//
1787
1788map<uint256, CAlert> mapAlerts;
1789CCriticalSection cs_mapAlerts;
1790
1791string GetWarnings(string strFor)
1792{
1793 int nPriority = 0;
1794 string strStatusBar;
1795 string strRPC;
1796 if (mapArgs.count("-testsafemode"))
1797 strRPC = "test";
1798
1799 // Misc warnings like out of disk space and clock is wrong
1800 if (strMiscWarning != "")
1801 {
1802 nPriority = 1000;
1803 strStatusBar = strMiscWarning;
1804 }
1805
1806 // Longer invalid proof-of-work chain
1807 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
1808 {
1809 nPriority = 2000;
1810 strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.";
1811 }
1812
1813 // Alerts
1814 CRITICAL_BLOCK(cs_mapAlerts)
1815 {
1816 foreach(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
1817 {
1818 const CAlert& alert = item.second;
1819 if (alert.AppliesToMe() && alert.nPriority > nPriority)
1820 {
1821 nPriority = alert.nPriority;
1822 strStatusBar = alert.strStatusBar;
1823 strRPC = alert.strRPCError;
1824 }
1825 }
1826 }
1827
1828 if (strFor == "statusbar")
1829 return strStatusBar;
1830 else if (strFor == "rpc")
1831 return strRPC;
1832 assert(("GetWarnings() : invalid parameter", false));
1833 return "error";
1834}
1835
1836bool CAlert::ProcessAlert()
1837{
1838 if (!CheckSignature())
1839 return false;
1840 if (!IsInEffect())
1841 return false;
1842
1843 CRITICAL_BLOCK(cs_mapAlerts)
1844 {
1845 // Cancel previous alerts
1846 for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
1847 {
1848 const CAlert& alert = (*mi).second;
1849 if (Cancels(alert))
1850 {
1851 printf("cancelling alert %d\n", alert.nID);
1852 mapAlerts.erase(mi++);
1853 }
1854 else if (!alert.IsInEffect())
1855 {
1856 printf("expiring alert %d\n", alert.nID);
1857 mapAlerts.erase(mi++);
1858 }
1859 else
1860 mi++;
1861 }
1862
1863 // Check if this alert has been cancelled
1864 foreach(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
1865 {
1866 const CAlert& alert = item.second;
1867 if (alert.Cancels(*this))
1868 {
1869 printf("alert already cancelled by %d\n", alert.nID);
1870 return false;
1871 }
1872 }
1873
1874 // Add to mapAlerts
1875 mapAlerts.insert(make_pair(GetHash(), *this));
1876 }
1877
1878 printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
1879 MainFrameRepaint();
1880 return true;
1881}
1882
1883
1884
1885
1886
1887
1888
1889
1890//////////////////////////////////////////////////////////////////////////////
1891//
1892// Messages
1893//
1894
1895
1896bool AlreadyHave(CTxDB& txdb, const CInv& inv)
1897{
1898 switch (inv.type)
1899 {
1900 case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
1901 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
1902 }
1903 // Don't know what it is, just say we already got one
1904 return true;
1905}
1906
1907
1908
1909
1910
1911
1912
1913bool ProcessMessages(CNode* pfrom)
1914{
1915 CDataStream& vRecv = pfrom->vRecv;
1916 if (vRecv.empty())
1917 return true;
1918 //if (fDebug)
1919 // printf("ProcessMessages(%u bytes)\n", vRecv.size());
1920
1921 //
1922 // Message format
1923 // (4) message start
1924 // (12) command
1925 // (4) size
1926 // (4) checksum
1927 // (x) data
1928 //
1929
1930 loop
1931 {
1932 // Scan for message start
1933 CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
1934 int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
1935 if (vRecv.end() - pstart < nHeaderSize)
1936 {
1937 if (vRecv.size() > nHeaderSize)
1938 {
1939 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
1940 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
1941 }
1942 break;
1943 }
1944 if (pstart - vRecv.begin() > 0)
1945 printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
1946 vRecv.erase(vRecv.begin(), pstart);
1947
1948 // Read header
1949 vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
1950 CMessageHeader hdr;
1951 vRecv >> hdr;
1952 if (!hdr.IsValid())
1953 {
1954 printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
1955 continue;
1956 }
1957 string strCommand = hdr.GetCommand();
1958
1959 // Message size
1960 unsigned int nMessageSize = hdr.nMessageSize;
1961 if (nMessageSize > MAX_SIZE)
1962 {
1963 printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
1964 continue;
1965 }
1966 if (nMessageSize > vRecv.size())
1967 {
1968 // Rewind and wait for rest of message
1969 ///// need a mechanism to give up waiting for overlong message size error
1970 vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
1971 break;
1972 }
1973
1974 // Copy message to its own buffer
1975 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
1976 vRecv.ignore(nMessageSize);
1977
1978 // Checksum
1979 if (vRecv.GetVersion() >= 209)
1980 {
1981 uint256 hash = Hash(vMsg.begin(), vMsg.end());
1982 unsigned int nChecksum = 0;
1983 memcpy(&nChecksum, &hash, sizeof(nChecksum));
1984 if (nChecksum != hdr.nChecksum)
1985 {
1986 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
1987 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
1988 continue;
1989 }
1990 }
1991
1992 // Process message
1993 bool fRet = false;
1994 try
1995 {
1996 CRITICAL_BLOCK(cs_main)
1997 fRet = ProcessMessage(pfrom, strCommand, vMsg);
1998 if (fShutdown)
1999 return true;
2000 }
2001 catch (std::ios_base::failure& e)
2002 {
2003 if (strstr(e.what(), "end of data"))
2004 {
2005 // Allow exceptions from underlength message on vRecv
2006 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand.c_str(), nMessageSize, e.what());
2007 }
2008 else if (strstr(e.what(), "size too large"))
2009 {
2010 // Allow exceptions from overlong size
2011 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
2012 }
2013 else
2014 {
2015 PrintException(&e, "ProcessMessage()");
2016 }
2017 }
2018 catch (std::exception& e) {
2019 PrintException(&e, "ProcessMessage()");
2020 } catch (...) {
2021 PrintException(NULL, "ProcessMessage()");
2022 }
2023
2024 if (!fRet)
2025 printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
2026 }
2027
2028 vRecv.Compact();
2029 return true;
2030}
2031
2032
2033
2034
2035bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
2036{
2037 static map<unsigned int, vector<unsigned char> > mapReuseKey;
2038 RandAddSeedPerfmon();
2039 if (fDebug)
2040 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
2041 printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
2042 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
2043 {
2044 printf("dropmessagestest DROPPING RECV MESSAGE\n");
2045 return true;
2046 }
2047
2048
2049
2050
2051
2052 if (strCommand == "version")
2053 {
2054 // Each connection can only send one version message
2055 if (pfrom->nVersion != 0)
2056 return false;
2057
2058 int64 nTime;
2059 CAddress addrMe;
2060 CAddress addrFrom;
2061 uint64 nNonce = 1;
2062 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
2063 if (pfrom->nVersion == 10300)
2064 pfrom->nVersion = 300;
2065 if (pfrom->nVersion >= 106 && !vRecv.empty())
2066 vRecv >> addrFrom >> nNonce;
2067 if (pfrom->nVersion >= 106 && !vRecv.empty())
2068 vRecv >> pfrom->strSubVer;
2069 if (pfrom->nVersion >= 209 && !vRecv.empty())
2070 vRecv >> pfrom->nStartingHeight;
2071
2072 if (pfrom->nVersion == 0)
2073 return false;
2074
2075 // Disconnect if we connected to ourself
2076 if (nNonce == nLocalHostNonce && nNonce > 1)
2077 {
2078 pfrom->fDisconnect = true;
2079 return true;
2080 }
2081
2082 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
2083 if (pfrom->fClient)
2084 {
2085 pfrom->vSend.nType |= SER_BLOCKHEADERONLY;
2086 pfrom->vRecv.nType |= SER_BLOCKHEADERONLY;
2087 }
2088
2089 AddTimeData(pfrom->addr.ip, nTime);
2090
2091 // Change version
2092 if (pfrom->nVersion >= 209)
2093 pfrom->PushMessage("verack");
2094 pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
2095 if (pfrom->nVersion < 209)
2096 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
2097
2098 // Ask the first connected node for block updates
2099 static int nAskedForBlocks;
2100 if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1))
2101 {
2102 nAskedForBlocks++;
2103 pfrom->PushGetBlocks(pindexBest, uint256(0));
2104 }
2105
2106 // Relay alerts
2107 CRITICAL_BLOCK(cs_mapAlerts)
2108 foreach(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
2109 item.second.RelayTo(pfrom);
2110
2111 pfrom->fSuccessfullyConnected = true;
2112
2113 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
2114 }
2115
2116
2117 else if (pfrom->nVersion == 0)
2118 {
2119 // Must have a version message before anything else
2120 return false;
2121 }
2122
2123
2124 else if (strCommand == "verack")
2125 {
2126 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
2127 }
2128
2129
2130 else if (strCommand == "addr")
2131 {
2132 vector<CAddress> vAddr;
2133 vRecv >> vAddr;
2134 if (pfrom->nVersion < 200) // don't want addresses from 0.1.5
2135 return true;
2136 if (pfrom->nVersion < 209 && mapAddresses.size() > 1000) // don't want addr from 0.2.0 unless seeding
2137 return true;
2138 if (vAddr.size() > 1000)
2139 return error("message addr size() = %d", vAddr.size());
2140
2141 // Store the new addresses
2142 foreach(CAddress& addr, vAddr)
2143 {
2144 if (fShutdown)
2145 return true;
2146 // ignore IPv6 for now, since it isn't implemented anyway
2147 if (!addr.IsIPv4())
2148 continue;
2149 addr.nTime = GetAdjustedTime() - 2 * 60 * 60;
2150 if (pfrom->fGetAddr || vAddr.size() > 10)
2151 addr.nTime -= 5 * 24 * 60 * 60;
2152 AddAddress(addr);
2153 pfrom->AddAddressKnown(addr);
2154 if (!pfrom->fGetAddr && addr.IsRoutable())
2155 {
2156 // Relay to a limited number of other nodes
2157 CRITICAL_BLOCK(cs_vNodes)
2158 {
2159 // Use deterministic randomness to send to
2160 // the same places for 12 hours at a time
2161 static uint256 hashSalt;
2162 if (hashSalt == 0)
2163 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
2164 uint256 hashRand = addr.ip ^ ((GetTime()+addr.ip)/(12*60*60)) ^ hashSalt;
2165 multimap<uint256, CNode*> mapMix;
2166 foreach(CNode* pnode, vNodes)
2167 mapMix.insert(make_pair(hashRand = Hash(BEGIN(hashRand), END(hashRand)), pnode));
2168 int nRelayNodes = 4;
2169 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
2170 ((*mi).second)->PushAddress(addr);
2171 }
2172 }
2173 }
2174 if (vAddr.size() < 1000)
2175 pfrom->fGetAddr = false;
2176 }
2177
2178
2179 else if (strCommand == "inv")
2180 {
2181 vector<CInv> vInv;
2182 vRecv >> vInv;
2183 if (vInv.size() > 50000)
2184 return error("message inv size() = %d", vInv.size());
2185
2186 CTxDB txdb("r");
2187 foreach(const CInv& inv, vInv)
2188 {
2189 if (fShutdown)
2190 return true;
2191 pfrom->AddInventoryKnown(inv);
2192
2193 bool fAlreadyHave = AlreadyHave(txdb, inv);
2194 printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
2195
2196 if (!fAlreadyHave)
2197 pfrom->AskFor(inv);
2198 else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
2199 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
2200
2201 // Track requests for our stuff
2202 CRITICAL_BLOCK(cs_mapRequestCount)
2203 {
2204 map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
2205 if (mi != mapRequestCount.end())
2206 (*mi).second++;
2207 }
2208 }
2209 }
2210
2211
2212 else if (strCommand == "getdata")
2213 {
2214 vector<CInv> vInv;
2215 vRecv >> vInv;
2216 if (vInv.size() > 50000)
2217 return error("message getdata size() = %d", vInv.size());
2218
2219 foreach(const CInv& inv, vInv)
2220 {
2221 if (fShutdown)
2222 return true;
2223 printf("received getdata for: %s\n", inv.ToString().c_str());
2224
2225 if (inv.type == MSG_BLOCK)
2226 {
2227 // Send block from disk
2228 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
2229 if (mi != mapBlockIndex.end())
2230 {
2231 //// could optimize this to send header straight from blockindex for client
2232 CBlock block;
2233 block.ReadFromDisk((*mi).second, !pfrom->fClient);
2234 pfrom->PushMessage("block", block);
2235
2236 // Trigger them to send a getblocks request for the next batch of inventory
2237 if (inv.hash == pfrom->hashContinue)
2238 {
2239 // Bypass PushInventory, this must send even if redundant,
2240 // and we want it right after the last block so they don't
2241 // wait for other stuff first.
2242 vector<CInv> vInv;
2243 vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
2244 pfrom->PushMessage("inv", vInv);
2245 pfrom->hashContinue = 0;
2246 }
2247 }
2248 }
2249 else if (inv.IsKnownType())
2250 {
2251 // Send stream from relay memory
2252 CRITICAL_BLOCK(cs_mapRelay)
2253 {
2254 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
2255 if (mi != mapRelay.end())
2256 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
2257 }
2258 }
2259
2260 // Track requests for our stuff
2261 CRITICAL_BLOCK(cs_mapRequestCount)
2262 {
2263 map<uint256, int>::iterator mi = mapRequestCount.find(inv.hash);
2264 if (mi != mapRequestCount.end())
2265 (*mi).second++;
2266 }
2267 }
2268 }
2269
2270
2271 else if (strCommand == "getblocks")
2272 {
2273 CBlockLocator locator;
2274 uint256 hashStop;
2275 vRecv >> locator >> hashStop;
2276
2277 // Find the first block the caller has in the main chain
2278 CBlockIndex* pindex = locator.GetBlockIndex();
2279
2280 // Send the rest of the chain
2281 if (pindex)
2282 pindex = pindex->pnext;
2283 int nLimit = 500 + locator.GetDistanceBack();
2284 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
2285 for (; pindex; pindex = pindex->pnext)
2286 {
2287 if (pindex->GetBlockHash() == hashStop)
2288 {
2289 printf(" getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str());
2290 break;
2291 }
2292 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
2293 if (--nLimit <= 0)
2294 {
2295 // When this block is requested, we'll send an inv that'll make them
2296 // getblocks the next batch of inventory.
2297 printf(" getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str());
2298 pfrom->hashContinue = pindex->GetBlockHash();
2299 break;
2300 }
2301 }
2302 }
2303
2304
2305 else if (strCommand == "tx")
2306 {
2307 vector<uint256> vWorkQueue;
2308 CDataStream vMsg(vRecv);
2309 CTransaction tx;
2310 vRecv >> tx;
2311
2312 CInv inv(MSG_TX, tx.GetHash());
2313 pfrom->AddInventoryKnown(inv);
2314
2315 bool fMissingInputs = false;
2316 if (tx.AcceptTransaction(true, &fMissingInputs))
2317 {
2318 AddToWalletIfMine(tx, NULL);
2319 RelayMessage(inv, vMsg);
2320 mapAlreadyAskedFor.erase(inv);
2321 vWorkQueue.push_back(inv.hash);
2322
2323 // Recursively process any orphan transactions that depended on this one
2324 for (int i = 0; i < vWorkQueue.size(); i++)
2325 {
2326 uint256 hashPrev = vWorkQueue[i];
2327 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
2328 mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
2329 ++mi)
2330 {
2331 const CDataStream& vMsg = *((*mi).second);
2332 CTransaction tx;
2333 CDataStream(vMsg) >> tx;
2334 CInv inv(MSG_TX, tx.GetHash());
2335
2336 if (tx.AcceptTransaction(true))
2337 {
2338 printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
2339 AddToWalletIfMine(tx, NULL);
2340 RelayMessage(inv, vMsg);
2341 mapAlreadyAskedFor.erase(inv);
2342 vWorkQueue.push_back(inv.hash);
2343 }
2344 }
2345 }
2346
2347 foreach(uint256 hash, vWorkQueue)
2348 EraseOrphanTx(hash);
2349 }
2350 else if (fMissingInputs)
2351 {
2352 printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,6).c_str());
2353 AddOrphanTx(vMsg);
2354 }
2355 }
2356
2357
2358 else if (strCommand == "block")
2359 {
2360 auto_ptr<CBlock> pblock(new CBlock);
2361 vRecv >> *pblock;
2362
2363 //// debug print
2364 printf("received block %s\n", pblock->GetHash().ToString().substr(0,20).c_str());
2365 // pblock->print();
2366
2367 CInv inv(MSG_BLOCK, pblock->GetHash());
2368 pfrom->AddInventoryKnown(inv);
2369
2370 if (ProcessBlock(pfrom, pblock.release()))
2371 mapAlreadyAskedFor.erase(inv);
2372 }
2373
2374
2375 else if (strCommand == "getaddr")
2376 {
2377 // This includes all nodes that are currently online,
2378 // since they rebroadcast an addr every 24 hours
2379 pfrom->vAddrToSend.clear();
2380 int64 nSince = GetAdjustedTime() - 12 * 60 * 60; // in the last 12 hours
2381 CRITICAL_BLOCK(cs_mapAddresses)
2382 {
2383 unsigned int nSize = mapAddresses.size();
2384 foreach(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
2385 {
2386 if (fShutdown)
2387 return true;
2388 const CAddress& addr = item.second;
2389 if (addr.nTime > nSince)
2390 pfrom->PushAddress(addr);
2391 }
2392 }
2393 }
2394
2395
2396 else if (strCommand == "checkorder")
2397 {
2398 uint256 hashReply;
2399 CWalletTx order;
2400 vRecv >> hashReply >> order;
2401
2402 /// we have a chance to check the order here
2403
2404 // Keep giving the same key to the same ip until they use it
2405 if (!mapReuseKey.count(pfrom->addr.ip))
2406 mapReuseKey[pfrom->addr.ip] = GenerateNewKey();
2407
2408 // Send back approval of order and pubkey to use
2409 CScript scriptPubKey;
2410 scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
2411 pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
2412 }
2413
2414
2415 else if (strCommand == "submitorder")
2416 {
2417 uint256 hashReply;
2418 CWalletTx wtxNew;
2419 vRecv >> hashReply >> wtxNew;
2420 wtxNew.fFromMe = false;
2421
2422 // Broadcast
2423 if (!wtxNew.AcceptWalletTransaction())
2424 {
2425 pfrom->PushMessage("reply", hashReply, (int)1);
2426 return error("submitorder AcceptWalletTransaction() failed, returning error 1");
2427 }
2428 wtxNew.fTimeReceivedIsTxTime = true;
2429 AddToWallet(wtxNew);
2430 wtxNew.RelayWalletTransaction();
2431 mapReuseKey.erase(pfrom->addr.ip);
2432
2433 // Send back confirmation
2434 pfrom->PushMessage("reply", hashReply, (int)0);
2435 }
2436
2437
2438 else if (strCommand == "reply")
2439 {
2440 uint256 hashReply;
2441 vRecv >> hashReply;
2442
2443 CRequestTracker tracker;
2444 CRITICAL_BLOCK(pfrom->cs_mapRequests)
2445 {
2446 map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
2447 if (mi != pfrom->mapRequests.end())
2448 {
2449 tracker = (*mi).second;
2450 pfrom->mapRequests.erase(mi);
2451 }
2452 }
2453 if (!tracker.IsNull())
2454 tracker.fn(tracker.param1, vRecv);
2455 }
2456
2457
2458 else if (strCommand == "ping")
2459 {
2460 }
2461
2462
2463 else if (strCommand == "alert")
2464 {
2465 CAlert alert;
2466 vRecv >> alert;
2467
2468 if (alert.ProcessAlert())
2469 {
2470 // Relay
2471 pfrom->setKnown.insert(alert.GetHash());
2472 CRITICAL_BLOCK(cs_vNodes)
2473 foreach(CNode* pnode, vNodes)
2474 alert.RelayTo(pnode);
2475 }
2476 }
2477
2478
2479 else
2480 {
2481 // Ignore unknown commands for extensibility
2482 }
2483
2484
2485 // Update the last seen time for this node's address
2486 if (pfrom->fNetworkNode)
2487 if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
2488 AddressCurrentlyConnected(pfrom->addr);
2489
2490
2491 return true;
2492}
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502bool SendMessages(CNode* pto, bool fSendTrickle)
2503{
2504 CRITICAL_BLOCK(cs_main)
2505 {
2506 // Don't send anything until we get their version message
2507 if (pto->nVersion == 0)
2508 return true;
2509
2510 // Keep-alive ping
2511 if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
2512 pto->PushMessage("ping");
2513
2514 // Address refresh broadcast
2515 static int64 nLastRebroadcast;
2516 if (GetTime() - nLastRebroadcast > 24 * 60 * 60) // every 24 hours
2517 {
2518 nLastRebroadcast = GetTime();
2519 CRITICAL_BLOCK(cs_vNodes)
2520 {
2521 foreach(CNode* pnode, vNodes)
2522 {
2523 // Periodically clear setAddrKnown to allow refresh broadcasts
2524 pnode->setAddrKnown.clear();
2525
2526 // Rebroadcast our address
2527 if (addrLocalHost.IsRoutable() && !fUseProxy)
2528 pnode->PushAddress(addrLocalHost);
2529 }
2530 }
2531 }
2532
2533 // Resend wallet transactions that haven't gotten in a block yet
2534 ResendWalletTransactions();
2535
2536
2537 //
2538 // Message: addr
2539 //
2540 if (fSendTrickle)
2541 {
2542 vector<CAddress> vAddr;
2543 vAddr.reserve(pto->vAddrToSend.size());
2544 foreach(const CAddress& addr, pto->vAddrToSend)
2545 {
2546 // returns true if wasn't already contained in the set
2547 if (pto->setAddrKnown.insert(addr).second)
2548 {
2549 vAddr.push_back(addr);
2550 // receiver rejects addr messages larger than 1000
2551 if (vAddr.size() >= 1000)
2552 {
2553 pto->PushMessage("addr", vAddr);
2554 vAddr.clear();
2555 }
2556 }
2557 }
2558 pto->vAddrToSend.clear();
2559 if (!vAddr.empty())
2560 pto->PushMessage("addr", vAddr);
2561 }
2562
2563
2564 //
2565 // Message: inventory
2566 //
2567 vector<CInv> vInv;
2568 vector<CInv> vInvWait;
2569 CRITICAL_BLOCK(pto->cs_inventory)
2570 {
2571 vInv.reserve(pto->vInventoryToSend.size());
2572 vInvWait.reserve(pto->vInventoryToSend.size());
2573 foreach(const CInv& inv, pto->vInventoryToSend)
2574 {
2575 if (pto->setInventoryKnown.count(inv))
2576 continue;
2577
2578 // trickle out tx inv to protect privacy
2579 if (inv.type == MSG_TX && !fSendTrickle)
2580 {
2581 // 1/4 of tx invs blast to all immediately
2582 static uint256 hashSalt;
2583 if (hashSalt == 0)
2584 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
2585 uint256 hashRand = inv.hash ^ hashSalt;
2586 hashRand = Hash(BEGIN(hashRand), END(hashRand));
2587 bool fTrickleWait = ((hashRand & 3) != 0);
2588
2589 // always trickle our own transactions
2590 if (!fTrickleWait)
2591 {
2592 TRY_CRITICAL_BLOCK(cs_mapWallet)
2593 {
2594 map<uint256, CWalletTx>::iterator mi = mapWallet.find(inv.hash);
2595 if (mi != mapWallet.end())
2596 {
2597 CWalletTx& wtx = (*mi).second;
2598 if (wtx.fFromMe)
2599 fTrickleWait = true;
2600 }
2601 }
2602 }
2603
2604 if (fTrickleWait)
2605 {
2606 vInvWait.push_back(inv);
2607 continue;
2608 }
2609 }
2610
2611 // returns true if wasn't already contained in the set
2612 if (pto->setInventoryKnown.insert(inv).second)
2613 {
2614 vInv.push_back(inv);
2615 if (vInv.size() >= 1000)
2616 {
2617 pto->PushMessage("inv", vInv);
2618 vInv.clear();
2619 }
2620 }
2621 }
2622 pto->vInventoryToSend = vInvWait;
2623 }
2624 if (!vInv.empty())
2625 pto->PushMessage("inv", vInv);
2626
2627
2628 //
2629 // Message: getdata
2630 //
2631 vector<CInv> vGetData;
2632 int64 nNow = GetTime() * 1000000;
2633 CTxDB txdb("r");
2634 while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
2635 {
2636 const CInv& inv = (*pto->mapAskFor.begin()).second;
2637 if (!AlreadyHave(txdb, inv))
2638 {
2639 printf("sending getdata: %s\n", inv.ToString().c_str());
2640 vGetData.push_back(inv);
2641 if (vGetData.size() >= 1000)
2642 {
2643 pto->PushMessage("getdata", vGetData);
2644 vGetData.clear();
2645 }
2646 }
2647 pto->mapAskFor.erase(pto->mapAskFor.begin());
2648 }
2649 if (!vGetData.empty())
2650 pto->PushMessage("getdata", vGetData);
2651
2652 }
2653 return true;
2654}
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669//////////////////////////////////////////////////////////////////////////////
2670//
2671// BitcoinMiner
2672//
2673
2674void GenerateBitcoins(bool fGenerate)
2675{
2676 if (fGenerateBitcoins != fGenerate)
2677 {
2678 fGenerateBitcoins = fGenerate;
2679 CWalletDB().WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
2680 MainFrameRepaint();
2681 }
2682 if (fGenerateBitcoins)
2683 {
2684 int nProcessors = boost::thread::hardware_concurrency();
2685 printf("%d processors\n", nProcessors);
2686 if (nProcessors < 1)
2687 nProcessors = 1;
2688 if (fLimitProcessors && nProcessors > nLimitProcessors)
2689 nProcessors = nLimitProcessors;
2690 int nAddThreads = nProcessors - vnThreadsRunning[3];
2691 printf("Starting %d BitcoinMiner threads\n", nAddThreads);
2692 for (int i = 0; i < nAddThreads; i++)
2693 {
2694 if (!CreateThread(ThreadBitcoinMiner, NULL))
2695 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
2696 Sleep(10);
2697 }
2698 }
2699}
2700
2701void ThreadBitcoinMiner(void* parg)
2702{
2703 try
2704 {
2705 vnThreadsRunning[3]++;
2706 BitcoinMiner();
2707 vnThreadsRunning[3]--;
2708 }
2709 catch (std::exception& e) {
2710 vnThreadsRunning[3]--;
2711 PrintException(&e, "ThreadBitcoinMiner()");
2712 } catch (...) {
2713 vnThreadsRunning[3]--;
2714 PrintException(NULL, "ThreadBitcoinMiner()");
2715 }
2716 UIThreadCall(bind(CalledSetStatusBar, "", 0));
2717 nHPSTimerStart = 0;
2718 if (vnThreadsRunning[3] == 0)
2719 dHashesPerSec = 0;
2720 printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
2721}
2722
2723int FormatHashBlocks(void* pbuffer, unsigned int len)
2724{
2725 unsigned char* pdata = (unsigned char*)pbuffer;
2726 unsigned int blocks = 1 + ((len + 8) / 64);
2727 unsigned char* pend = pdata + 64 * blocks;
2728 memset(pdata + len, 0, 64 * blocks - len);
2729 pdata[len] = 0x80;
2730 unsigned int bits = len * 8;
2731 pend[-1] = (bits >> 0) & 0xff;
2732 pend[-2] = (bits >> 8) & 0xff;
2733 pend[-3] = (bits >> 16) & 0xff;
2734 pend[-4] = (bits >> 24) & 0xff;
2735 return blocks;
2736}
2737
2738using CryptoPP::ByteReverse;
2739
2740static const unsigned int pSHA256InitState[8] =
2741{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
2742
2743inline void SHA256Transform(void* pstate, void* pinput, const void* pinit)
2744{
2745 memcpy(pstate, pinit, 32);
2746 CryptoPP::SHA256::Transform((CryptoPP::word32*)pstate, (CryptoPP::word32*)pinput);
2747}
2748
2749static const int NPAR = 32;
2750extern void Double_BlockSHA256(const void* pin, void* pout, const void* pinit, unsigned int hash[8][NPAR], const void* init2);
2751
2752
2753
2754
2755void BitcoinMiner()
2756{
2757 printf("BitcoinMiner started\n");
2758 SetThreadPriority(THREAD_PRIORITY_LOWEST);
2759
2760 CKey key;
2761 key.MakeNewKey();
2762 CBigNum bnExtraNonce = 0;
2763 while (fGenerateBitcoins)
2764 {
2765 Sleep(50);
2766 if (fShutdown)
2767 return;
2768 while (vNodes.empty() || IsInitialBlockDownload())
2769 {
2770 Sleep(1000);
2771 if (fShutdown)
2772 return;
2773 if (!fGenerateBitcoins)
2774 return;
2775 }
2776
2777 unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
2778 CBlockIndex* pindexPrev = pindexBest;
2779 unsigned int nBits = GetNextWorkRequired(pindexPrev);
2780
2781
2782 //
2783 // Create coinbase tx
2784 //
2785 CTransaction txNew;
2786 txNew.vin.resize(1);
2787 txNew.vin[0].prevout.SetNull();
2788 txNew.vin[0].scriptSig << nBits << ++bnExtraNonce;
2789 txNew.vout.resize(1);
2790 txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG;
2791
2792
2793 //
2794 // Create new block
2795 //
2796 auto_ptr<CBlock> pblock(new CBlock());
2797 if (!pblock.get())
2798 return;
2799
2800 // Add our coinbase tx as first transaction
2801 pblock->vtx.push_back(txNew);
2802
2803 // Collect the latest transactions into the block
2804 int64 nFees = 0;
2805 CRITICAL_BLOCK(cs_main)
2806 CRITICAL_BLOCK(cs_mapTransactions)
2807 {
2808 CTxDB txdb("r");
2809 map<uint256, CTxIndex> mapTestPool;
2810 vector<char> vfAlreadyAdded(mapTransactions.size());
2811 bool fFoundSomething = true;
2812 uint64 nBlockSize = 0;
2813 while (fFoundSomething && nBlockSize < MAX_SIZE/2)
2814 {
2815 fFoundSomething = false;
2816 unsigned int n = 0;
2817 for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi, ++n)
2818 {
2819 if (vfAlreadyAdded[n])
2820 continue;
2821 CTransaction& tx = (*mi).second;
2822 if (tx.IsCoinBase() || !tx.IsFinal())
2823 continue;
2824 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
2825 if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE - 10000)
2826 continue;
2827
2828 // Transaction fee based on block size
2829 int64 nMinFee = tx.GetMinFee(nBlockSize);
2830
2831 map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
2832 if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee))
2833 continue;
2834 swap(mapTestPool, mapTestPoolTmp);
2835
2836 pblock->vtx.push_back(tx);
2837 nBlockSize += nTxSize;
2838 vfAlreadyAdded[n] = true;
2839 fFoundSomething = true;
2840 }
2841 }
2842 }
2843 pblock->nBits = nBits;
2844 pblock->vtx[0].vout[0].nValue = pblock->GetBlockValue(pindexPrev->nHeight+1, nFees);
2845 printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
2846
2847
2848 //
2849 // Prebuild hash buffer
2850 //
2851 struct tmpworkspace
2852 {
2853 struct unnamed2
2854 {
2855 int nVersion;
2856 uint256 hashPrevBlock;
2857 uint256 hashMerkleRoot;
2858 unsigned int nTime;
2859 unsigned int nBits;
2860 unsigned int nNonce;
2861 }
2862 block;
2863 unsigned char pchPadding0[64];
2864 uint256 hash1;
2865 unsigned char pchPadding1[64];
2866 };
2867 char tmpbuf[sizeof(tmpworkspace)+16];
2868 tmpworkspace& tmp = *(tmpworkspace*)alignup<16>(tmpbuf);
2869
2870 tmp.block.nVersion = pblock->nVersion;
2871 tmp.block.hashPrevBlock = pblock->hashPrevBlock = (pindexPrev ? pindexPrev->GetBlockHash() : 0);
2872 tmp.block.hashMerkleRoot = pblock->hashMerkleRoot = pblock->BuildMerkleTree();
2873 tmp.block.nTime = pblock->nTime = max((pindexPrev ? pindexPrev->GetMedianTimePast()+1 : 0), GetAdjustedTime());
2874 tmp.block.nBits = pblock->nBits = nBits;
2875 tmp.block.nNonce = pblock->nNonce = 0;
2876
2877 unsigned int nBlocks0 = FormatHashBlocks(&tmp.block, sizeof(tmp.block));
2878 unsigned int nBlocks1 = FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
2879
2880 // Byte swap all the input buffer
2881 for (int i = 0; i < sizeof(tmp)/4; i++)
2882 ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
2883
2884 // Precalc the first half of the first hash, which stays constant
2885 uint256 midstatebuf[2];
2886 uint256& midstate = *alignup<16>(midstatebuf);
2887 SHA256Transform(&midstate, &tmp.block, pSHA256InitState);
2888
2889
2890 //
2891 // Search
2892 //
2893 bool f4WaySSE2 = mapArgs.count("-4way");
2894 int64 nStart = GetTime();
2895 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
2896 uint256 hashbuf[2];
2897 uint256& hash = *alignup<16>(hashbuf);
2898 loop
2899 {
2900#ifdef FOURWAYSSE2
2901 if (f4WaySSE2)
2902 {
2903 // tcatm's 4-way SSE2 SHA-256
2904 tmp.block.nNonce += NPAR;
2905 unsigned int thashbuf[9][NPAR];
2906 unsigned int (&thash)[9][NPAR] = *alignup<16>(&thashbuf);
2907 Double_BlockSHA256((char*)&tmp.block + 64, &tmp.hash1, &midstate, thash, pSHA256InitState);
2908 ((unsigned short*)&hash)[14] = 0xffff;
2909 for (int j = 0; j < NPAR; j++)
2910 {
2911 if (thash[7][j] == 0)
2912 {
2913 for (int i = 0; i < sizeof(hash)/4; i++)
2914 ((unsigned int*)&hash)[i] = thash[i][j];
2915 pblock->nNonce = ByteReverse(tmp.block.nNonce + j);
2916 }
2917 }
2918 }
2919 else
2920#endif
2921 {
2922 // Crypto++ SHA-256
2923 tmp.block.nNonce++;
2924 SHA256Transform(&tmp.hash1, (char*)&tmp.block + 64, &midstate);
2925 SHA256Transform(&hash, &tmp.hash1, pSHA256InitState);
2926 }
2927
2928 if (((unsigned short*)&hash)[14] == 0)
2929 {
2930 // Byte swap the result after preliminary check
2931 for (int i = 0; i < sizeof(hash)/4; i++)
2932 ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
2933
2934 if (hash <= hashTarget)
2935 {
2936#ifdef FOURWAYSSE2
2937 if (!f4WaySSE2)
2938#endif
2939 pblock->nNonce = ByteReverse(tmp.block.nNonce);
2940 assert(hash == pblock->GetHash());
2941
2942 //// debug print
2943 printf("BitcoinMiner:\n");
2944 printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
2945 pblock->print();
2946 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
2947 printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
2948
2949 SetThreadPriority(THREAD_PRIORITY_NORMAL);
2950 CRITICAL_BLOCK(cs_main)
2951 {
2952 if (pindexPrev == pindexBest)
2953 {
2954 // Save key
2955 if (!AddKey(key))
2956 return;
2957 key.MakeNewKey();
2958
2959 // Track how many getdata requests this block gets
2960 CRITICAL_BLOCK(cs_mapRequestCount)
2961 mapRequestCount[pblock->GetHash()] = 0;
2962
2963 // Process this block the same as if we had received it from another node
2964 if (!ProcessBlock(NULL, pblock.release()))
2965 printf("ERROR in BitcoinMiner, ProcessBlock, block not accepted\n");
2966 }
2967 }
2968 SetThreadPriority(THREAD_PRIORITY_LOWEST);
2969
2970 Sleep(500);
2971 break;
2972 }
2973 }
2974
2975 // Update nTime every few seconds
2976 const unsigned int nMask = 0xffff;
2977 const int nHashesPerCycle = (nMask+1);
2978 if ((tmp.block.nNonce & nMask) == 0)
2979 {
2980 // Meter hashes/sec
2981 static int nCycleCounter;
2982 if (nHPSTimerStart == 0)
2983 {
2984 nHPSTimerStart = GetTimeMillis();
2985 nCycleCounter = 0;
2986 }
2987 else
2988 nCycleCounter++;
2989 if (GetTimeMillis() - nHPSTimerStart > 4000)
2990 {
2991 static CCriticalSection cs;
2992 CRITICAL_BLOCK(cs)
2993 {
2994 if (GetTimeMillis() - nHPSTimerStart > 4000)
2995 {
2996 dHashesPerSec = 1000.0 * nHashesPerCycle * nCycleCounter / (GetTimeMillis() - nHPSTimerStart);
2997 nHPSTimerStart = GetTimeMillis();
2998 nCycleCounter = 0;
2999 string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
3000 UIThreadCall(bind(CalledSetStatusBar, strStatus, 0));
3001 static int64 nLogTime;
3002 if (GetTime() - nLogTime > 30 * 60)
3003 {
3004 nLogTime = GetTime();
3005 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
3006 printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
3007 }
3008 }
3009 }
3010 }
3011
3012 // Check for stop or if block needs to be rebuilt
3013 if (fShutdown)
3014 return;
3015 if (!fGenerateBitcoins)
3016 return;
3017 if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
3018 return;
3019 if (vNodes.empty())
3020 break;
3021 if (tmp.block.nNonce == 0)
3022 break;
3023 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
3024 break;
3025 if (pindexPrev != pindexBest)
3026 break;
3027
3028 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
3029 tmp.block.nTime = ByteReverse(pblock->nTime);
3030 }
3031 }
3032 }
3033}
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052//////////////////////////////////////////////////////////////////////////////
3053//
3054// Actions
3055//
3056
3057
3058int64 GetBalance()
3059{
3060 int64 nStart = GetTimeMillis();
3061
3062 int64 nTotal = 0;
3063 CRITICAL_BLOCK(cs_mapWallet)
3064 {
3065 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3066 {
3067 CWalletTx* pcoin = &(*it).second;
3068 if (!pcoin->IsFinal() || pcoin->fSpent)
3069 continue;
3070 nTotal += pcoin->GetCredit(true);
3071 }
3072 }
3073
3074 //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
3075 return nTotal;
3076}
3077
3078
3079int GetRandInt(int nMax)
3080{
3081 return GetRand(nMax);
3082}
3083
3084bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet)
3085{
3086 setCoinsRet.clear();
3087
3088 // List of values less than target
3089 int64 nLowestLarger = INT64_MAX;
3090 CWalletTx* pcoinLowestLarger = NULL;
3091 vector<pair<int64, CWalletTx*> > vValue;
3092 int64 nTotalLower = 0;
3093
3094 CRITICAL_BLOCK(cs_mapWallet)
3095 {
3096 vector<CWalletTx*> vCoins;
3097 vCoins.reserve(mapWallet.size());
3098 for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
3099 vCoins.push_back(&(*it).second);
3100 random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
3101
3102 foreach(CWalletTx* pcoin, vCoins)
3103 {
3104 if (!pcoin->IsFinal() || pcoin->fSpent)
3105 continue;
3106 int64 n = pcoin->GetCredit();
3107 if (n <= 0)
3108 continue;
3109 if (n < nTargetValue)
3110 {
3111 vValue.push_back(make_pair(n, pcoin));
3112 nTotalLower += n;
3113 }
3114 else if (n == nTargetValue)
3115 {
3116 setCoinsRet.insert(pcoin);
3117 return true;
3118 }
3119 else if (n < nLowestLarger)
3120 {
3121 nLowestLarger = n;
3122 pcoinLowestLarger = pcoin;
3123 }
3124 }
3125 }
3126
3127 if (nTotalLower < nTargetValue)
3128 {
3129 if (pcoinLowestLarger == NULL)
3130 return false;
3131 setCoinsRet.insert(pcoinLowestLarger);
3132 return true;
3133 }
3134
3135 // Solve subset sum by stochastic approximation
3136 sort(vValue.rbegin(), vValue.rend());
3137 vector<char> vfIncluded;
3138 vector<char> vfBest(vValue.size(), true);
3139 int64 nBest = nTotalLower;
3140
3141 for (int nRep = 0; nRep < 1000 && nBest != nTargetValue; nRep++)
3142 {
3143 vfIncluded.assign(vValue.size(), false);
3144 int64 nTotal = 0;
3145 bool fReachedTarget = false;
3146 for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
3147 {
3148 for (int i = 0; i < vValue.size(); i++)
3149 {
3150 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
3151 {
3152 nTotal += vValue[i].first;
3153 vfIncluded[i] = true;
3154 if (nTotal >= nTargetValue)
3155 {
3156 fReachedTarget = true;
3157 if (nTotal < nBest)
3158 {
3159 nBest = nTotal;
3160 vfBest = vfIncluded;
3161 }
3162 nTotal -= vValue[i].first;
3163 vfIncluded[i] = false;
3164 }
3165 }
3166 }
3167 }
3168 }
3169
3170 // If the next larger is still closer, return it
3171 if (pcoinLowestLarger && nLowestLarger - nTargetValue <= nBest - nTargetValue)
3172 setCoinsRet.insert(pcoinLowestLarger);
3173 else
3174 {
3175 for (int i = 0; i < vValue.size(); i++)
3176 if (vfBest[i])
3177 setCoinsRet.insert(vValue[i].second);
3178
3179 //// debug print
3180 printf("SelectCoins() best subset: ");
3181 for (int i = 0; i < vValue.size(); i++)
3182 if (vfBest[i])
3183 printf("%s ", FormatMoney(vValue[i].first).c_str());
3184 printf("total %s\n", FormatMoney(nBest).c_str());
3185 }
3186
3187 return true;
3188}
3189
3190
3191
3192
3193bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CKey& keyRet, int64& nFeeRequiredRet)
3194{
3195 nFeeRequiredRet = 0;
3196 CRITICAL_BLOCK(cs_main)
3197 {
3198 // txdb must be opened before the mapWallet lock
3199 CTxDB txdb("r");
3200 CRITICAL_BLOCK(cs_mapWallet)
3201 {
3202 int64 nFee = nTransactionFee;
3203 loop
3204 {
3205 wtxNew.vin.clear();
3206 wtxNew.vout.clear();
3207 wtxNew.fFromMe = true;
3208 if (nValue < 0)
3209 return false;
3210 int64 nValueOut = nValue;
3211 int64 nTotalValue = nValue + nFee;
3212
3213 // Choose coins to use
3214 set<CWalletTx*> setCoins;
3215 if (!SelectCoins(nTotalValue, setCoins))
3216 return false;
3217 int64 nValueIn = 0;
3218 foreach(CWalletTx* pcoin, setCoins)
3219 nValueIn += pcoin->GetCredit();
3220
3221 // Fill a vout to the payee
3222 bool fChangeFirst = GetRand(2);
3223 if (!fChangeFirst)
3224 wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
3225
3226 // Fill a vout back to self with any change
3227 if (nValueIn > nTotalValue)
3228 {
3229 // Note: We use a new key here to keep it from being obvious which side is the change.
3230 // The drawback is that by not reusing a previous key, the change may be lost if a
3231 // backup is restored, if the backup doesn't have the new private key for the change.
3232 // If we reused the old key, it would be possible to add code to look for and
3233 // rediscover unknown transactions that were written with keys of ours to recover
3234 // post-backup change.
3235
3236 // New private key
3237 if (keyRet.IsNull())
3238 keyRet.MakeNewKey();
3239
3240 // Fill a vout to ourself, using same address type as the payment
3241 CScript scriptChange;
3242 if (scriptPubKey.GetBitcoinAddressHash160() != 0)
3243 scriptChange.SetBitcoinAddress(keyRet.GetPubKey());
3244 else
3245 scriptChange << keyRet.GetPubKey() << OP_CHECKSIG;
3246 wtxNew.vout.push_back(CTxOut(nValueIn - nTotalValue, scriptChange));
3247 }
3248
3249 // Fill a vout to the payee
3250 if (fChangeFirst)
3251 wtxNew.vout.push_back(CTxOut(nValueOut, scriptPubKey));
3252
3253 // Fill vin
3254 foreach(CWalletTx* pcoin, setCoins)
3255 for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
3256 if (pcoin->vout[nOut].IsMine())
3257 wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));
3258
3259 // Sign
3260 int nIn = 0;
3261 foreach(CWalletTx* pcoin, setCoins)
3262 for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
3263 if (pcoin->vout[nOut].IsMine())
3264 if (!SignSignature(*pcoin, wtxNew, nIn++))
3265 return false;
3266
3267 // Check that enough fee is included
3268 if (nFee < wtxNew.GetMinFee())
3269 {
3270 nFee = nFeeRequiredRet = wtxNew.GetMinFee();
3271 continue;
3272 }
3273
3274 // Fill vtxPrev by copying from previous transactions vtxPrev
3275 wtxNew.AddSupportingTransactions(txdb);
3276 wtxNew.fTimeReceivedIsTxTime = true;
3277
3278 break;
3279 }
3280 }
3281 }
3282 return true;
3283}
3284
3285// Call after CreateTransaction unless you want to abort
3286bool CommitTransaction(CWalletTx& wtxNew, const CKey& key)
3287{
3288 CRITICAL_BLOCK(cs_main)
3289 {
3290 printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
3291 CRITICAL_BLOCK(cs_mapWallet)
3292 {
3293 // This is only to keep the database open to defeat the auto-flush for the
3294 // duration of this scope. This is the only place where this optimization
3295 // maybe makes sense; please don't do it anywhere else.
3296 CWalletDB walletdb("r");
3297
3298 // Add the change's private key to wallet
3299 if (!key.IsNull() && !AddKey(key))
3300 throw runtime_error("CommitTransaction() : AddKey failed\n");
3301
3302 // Add tx to wallet, because if it has change it's also ours,
3303 // otherwise just for transaction history.
3304 AddToWallet(wtxNew);
3305
3306 // Mark old coins as spent
3307 set<CWalletTx*> setCoins;
3308 foreach(const CTxIn& txin, wtxNew.vin)
3309 setCoins.insert(&mapWallet[txin.prevout.hash]);
3310 foreach(CWalletTx* pcoin, setCoins)
3311 {
3312 pcoin->fSpent = true;
3313 pcoin->WriteToDisk();
3314 vWalletUpdated.push_back(pcoin->GetHash());
3315 }
3316 }
3317
3318 // Track how many getdata requests our transaction gets
3319 CRITICAL_BLOCK(cs_mapRequestCount)
3320 mapRequestCount[wtxNew.GetHash()] = 0;
3321
3322 // Broadcast
3323 if (!wtxNew.AcceptTransaction())
3324 {
3325 // This must not fail. The transaction has already been signed and recorded.
3326 printf("CommitTransaction() : Error: Transaction not valid");
3327 return false;
3328 }
3329 wtxNew.RelayWalletTransaction();
3330 }
3331 MainFrameRepaint();
3332 return true;
3333}
3334
3335
3336
3337
3338string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
3339{
3340 CRITICAL_BLOCK(cs_main)
3341 {
3342 CKey key;
3343 int64 nFeeRequired;
3344 if (!CreateTransaction(scriptPubKey, nValue, wtxNew, key, nFeeRequired))
3345 {
3346 string strError;
3347 if (nValue + nFeeRequired > GetBalance())
3348 strError = strprintf(_("Error: This is an oversized transaction that requires a transaction fee of %s "), FormatMoney(nFeeRequired).c_str());
3349 else
3350 strError = _("Error: Transaction creation failed ");
3351 printf("SendMoney() : %s", strError.c_str());
3352 return strError;
3353 }
3354
3355 if (fAskFee && !ThreadSafeAskFee(nFeeRequired, _("Sending..."), NULL))
3356 return "ABORTED";
3357
3358 if (!CommitTransaction(wtxNew, key))
3359 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.");
3360 }
3361 MainFrameRepaint();
3362 return "";
3363}
3364
3365
3366
3367string SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee)
3368{
3369 // Check amount
3370 if (nValue <= 0)
3371 return _("Invalid amount");
3372 if (nValue + nTransactionFee > GetBalance())
3373 return _("Insufficient funds");
3374
3375 // Parse bitcoin address
3376 CScript scriptPubKey;
3377 if (!scriptPubKey.SetBitcoinAddress(strAddress))
3378 return _("Invalid bitcoin address");
3379
3380 return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
3381}
This page took 0.360465 seconds and 4 git commands to generate.