genesis 1
genesis 2
genesis 3
genesis 4
genesis 5 #include "headers.h"
genesis 6 #include "checkpoints.h"
genesis 7 #include "db.h"
genesis 8 #include "net.h"
genesis 9 #include "init.h"
genesis 10 #include <boost/filesystem.hpp>
genesis 11 #include <boost/filesystem/fstream.hpp>
genesis 12
genesis 13 using namespace std;
genesis 14 using namespace boost;
genesis 15
genesis 16
genesis 17
genesis 18
genesis 19
genesis 20 CCriticalSection cs_setpwalletRegistered;
genesis 21 set<CWallet*> setpwalletRegistered;
genesis 22
genesis 23 CCriticalSection cs_main;
genesis 24
genesis 25 static map<uint256, CTransaction> mapTransactions;
genesis 26 CCriticalSection cs_mapTransactions;
genesis 27 unsigned int nTransactionsUpdated = 0;
genesis 28 map<COutPoint, CInPoint> mapNextTx;
genesis 29
genesis 30 map<uint256, CBlockIndex*> mapBlockIndex;
genesis 31 uint256 hashGenesisBlock("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f");
genesis 32 static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
genesis 33 CBlockIndex* pindexGenesisBlock = NULL;
genesis 34 int nBestHeight = -1;
genesis 35 CBigNum bnBestChainWork = 0;
genesis 36 CBigNum bnBestInvalidWork = 0;
genesis 37 uint256 hashBestChain = 0;
genesis 38 CBlockIndex* pindexBest = NULL;
genesis 39 int64 nTimeBestReceived = 0;
genesis 40
genesis 41 CMedianFilter<int> cPeerBlockCounts(5, 0);
genesis 42
genesis 43 map<uint256, CBlock*> mapOrphanBlocks;
genesis 44 multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
genesis 45
genesis 46 map<uint256, CDataStream*> mapOrphanTransactions;
genesis 47 multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
genesis 48
genesis 49
genesis 50 double dHashesPerSec;
genesis 51 int64 nHPSTimerStart;
genesis 52
genesis 53
genesis 54 int fGenerateBitcoins = false;
genesis 55 int64 nTransactionFee = 0;
genesis 56 int fLimitProcessors = false;
genesis 57 int nLimitProcessors = 1;
genesis 58 int fMinimizeToTray = true;
genesis 59 int fMinimizeOnClose = true;
genesis 60 #if USE_UPNP
genesis 61 int fUseUPnP = true;
genesis 62 #else
genesis 63 int fUseUPnP = false;
genesis 64 #endif
genesis 65
genesis 66
genesis 67
genesis 68
genesis 69
genesis 70
genesis 71
genesis 72
genesis 73
genesis 74
genesis 75 void RegisterWallet(CWallet* pwalletIn)
genesis 76 {
genesis 77 CRITICAL_BLOCK(cs_setpwalletRegistered)
genesis 78 {
genesis 79 setpwalletRegistered.insert(pwalletIn);
genesis 80 }
genesis 81 }
genesis 82
genesis 83 void UnregisterWallet(CWallet* pwalletIn)
genesis 84 {
genesis 85 CRITICAL_BLOCK(cs_setpwalletRegistered)
genesis 86 {
genesis 87 setpwalletRegistered.erase(pwalletIn);
genesis 88 }
genesis 89 }
genesis 90
genesis 91
genesis 92 bool static IsFromMe(CTransaction& tx)
genesis 93 {
genesis 94 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 95 if (pwallet->IsFromMe(tx))
genesis 96 return true;
genesis 97 return false;
genesis 98 }
genesis 99
genesis 100
genesis 101 bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx)
genesis 102 {
genesis 103 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 104 if (pwallet->GetTransaction(hashTx,wtx))
genesis 105 return true;
genesis 106 return false;
genesis 107 }
genesis 108
genesis 109
genesis 110 void static EraseFromWallets(uint256 hash)
genesis 111 {
genesis 112 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 113 pwallet->EraseFromWallet(hash);
genesis 114 }
genesis 115
genesis 116
genesis 117 void static SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL, bool fUpdate = false)
genesis 118 {
genesis 119 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 120 pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate);
genesis 121 }
genesis 122
genesis 123
genesis 124 void static SetBestChain(const CBlockLocator& loc)
genesis 125 {
genesis 126 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 127 pwallet->SetBestChain(loc);
genesis 128 }
genesis 129
genesis 130
genesis 131 void static UpdatedTransaction(const uint256& hashTx)
genesis 132 {
genesis 133 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 134 pwallet->UpdatedTransaction(hashTx);
genesis 135 }
genesis 136
genesis 137
genesis 138 void static PrintWallets(const CBlock& block)
genesis 139 {
genesis 140 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 141 pwallet->PrintWallet(block);
genesis 142 }
genesis 143
genesis 144
genesis 145 void static Inventory(const uint256& hash)
genesis 146 {
genesis 147 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 148 pwallet->Inventory(hash);
genesis 149 }
genesis 150
genesis 151
genesis 152 void static ResendWalletTransactions()
genesis 153 {
genesis 154 BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered)
genesis 155 pwallet->ResendWalletTransactions();
genesis 156 }
genesis 157
genesis 158
genesis 159
genesis 160
genesis 161
genesis 162
genesis 163
genesis 164
genesis 165
genesis 166
genesis 167
genesis 168
genesis 169 void AddOrphanTx(const CDataStream& vMsg)
genesis 170 {
genesis 171 CTransaction tx;
genesis 172 CDataStream(vMsg) >> tx;
genesis 173 uint256 hash = tx.GetHash();
genesis 174 if (mapOrphanTransactions.count(hash))
genesis 175 return;
genesis 176
genesis 177 CDataStream* pvMsg = mapOrphanTransactions[hash] = new CDataStream(vMsg);
genesis 178 BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis 179 mapOrphanTransactionsByPrev.insert(make_pair(txin.prevout.hash, pvMsg));
genesis 180 }
genesis 181
genesis 182 void static EraseOrphanTx(uint256 hash)
genesis 183 {
genesis 184 if (!mapOrphanTransactions.count(hash))
genesis 185 return;
genesis 186 const CDataStream* pvMsg = mapOrphanTransactions[hash];
genesis 187 CTransaction tx;
genesis 188 CDataStream(*pvMsg) >> tx;
genesis 189 BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis 190 {
genesis 191 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(txin.prevout.hash);
genesis 192 mi != mapOrphanTransactionsByPrev.upper_bound(txin.prevout.hash);)
genesis 193 {
genesis 194 if ((*mi).second == pvMsg)
genesis 195 mapOrphanTransactionsByPrev.erase(mi++);
genesis 196 else
genesis 197 mi++;
genesis 198 }
genesis 199 }
genesis 200 delete pvMsg;
genesis 201 mapOrphanTransactions.erase(hash);
genesis 202 }
genesis 203
genesis 204 int LimitOrphanTxSize(int nMaxOrphans)
genesis 205 {
genesis 206 int nEvicted = 0;
genesis 207 while (mapOrphanTransactions.size() > nMaxOrphans)
genesis 208 {
genesis 209
genesis 210 std::vector<unsigned char> randbytes(32);
genesis 211 RAND_bytes(&randbytes[0], 32);
genesis 212 uint256 randomhash(randbytes);
genesis 213 map<uint256, CDataStream*>::iterator it = mapOrphanTransactions.lower_bound(randomhash);
genesis 214 if (it == mapOrphanTransactions.end())
genesis 215 it = mapOrphanTransactions.begin();
genesis 216 EraseOrphanTx(it->first);
genesis 217 ++nEvicted;
genesis 218 }
genesis 219 return nEvicted;
genesis 220 }
genesis 221
genesis 222
genesis 223
genesis 224
genesis 225
genesis 226
genesis 227
genesis 228
genesis 229
genesis 230
genesis 231
genesis 232
genesis 233 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout, CTxIndex& txindexRet)
genesis 234 {
genesis 235 SetNull();
genesis 236 if (!txdb.ReadTxIndex(prevout.hash, txindexRet))
genesis 237 return false;
genesis 238 if (!ReadFromDisk(txindexRet.pos))
genesis 239 return false;
genesis 240 if (prevout.n >= vout.size())
genesis 241 {
genesis 242 SetNull();
genesis 243 return false;
genesis 244 }
genesis 245 return true;
genesis 246 }
genesis 247
genesis 248 bool CTransaction::ReadFromDisk(CTxDB& txdb, COutPoint prevout)
genesis 249 {
genesis 250 CTxIndex txindex;
genesis 251 return ReadFromDisk(txdb, prevout, txindex);
genesis 252 }
genesis 253
genesis 254 bool CTransaction::ReadFromDisk(COutPoint prevout)
genesis 255 {
genesis 256 CTxDB txdb("r");
genesis 257 CTxIndex txindex;
genesis 258 return ReadFromDisk(txdb, prevout, txindex);
genesis 259 }
genesis 260
genesis 261
genesis 262
genesis 263 int CMerkleTx::SetMerkleBranch(const CBlock* pblock)
genesis 264 {
genesis 265 if (fClient)
genesis 266 {
genesis 267 if (hashBlock == 0)
genesis 268 return 0;
genesis 269 }
genesis 270 else
genesis 271 {
genesis 272 CBlock blockTmp;
genesis 273 if (pblock == NULL)
genesis 274 {
genesis 275
genesis 276 CTxIndex txindex;
genesis 277 if (!CTxDB("r").ReadTxIndex(GetHash(), txindex))
genesis 278 return 0;
genesis 279 if (!blockTmp.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos))
genesis 280 return 0;
genesis 281 pblock = &blockTmp;
genesis 282 }
genesis 283
genesis 284
genesis 285 hashBlock = pblock->GetHash();
genesis 286
genesis 287
genesis 288 for (nIndex = 0; nIndex < pblock->vtx.size(); nIndex++)
genesis 289 if (pblock->vtx[nIndex] == *(CTransaction*)this)
genesis 290 break;
genesis 291 if (nIndex == pblock->vtx.size())
genesis 292 {
genesis 293 vMerkleBranch.clear();
genesis 294 nIndex = -1;
genesis 295 printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
genesis 296 return 0;
genesis 297 }
genesis 298
genesis 299
genesis 300 vMerkleBranch = pblock->GetMerkleBranch(nIndex);
genesis 301 }
genesis 302
genesis 303
genesis 304 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis 305 if (mi == mapBlockIndex.end())
genesis 306 return 0;
genesis 307 CBlockIndex* pindex = (*mi).second;
genesis 308 if (!pindex || !pindex->IsInMainChain())
genesis 309 return 0;
genesis 310
genesis 311 return pindexBest->nHeight - pindex->nHeight + 1;
genesis 312 }
genesis 313
genesis 314
genesis 315
genesis 316
genesis 317
genesis 318
genesis 319
genesis 320 bool CTransaction::CheckTransaction() const
genesis 321 {
genesis 322
genesis 323 if (vin.empty())
genesis 324 return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
genesis 325 if (vout.empty())
genesis 326 return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
genesis 327
genesis 328 if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
genesis 329 return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
genesis 330
genesis 331
genesis 332 int64 nValueOut = 0;
genesis 333 BOOST_FOREACH(const CTxOut& txout, vout)
genesis 334 {
genesis 335 if (txout.nValue < 0)
genesis 336 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative"));
genesis 337 if (txout.nValue > MAX_MONEY)
genesis 338 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
genesis 339 nValueOut += txout.nValue;
genesis 340 if (!MoneyRange(nValueOut))
genesis 341 return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
genesis 342 }
genesis 343
genesis 344
genesis 345 set<COutPoint> vInOutPoints;
genesis 346 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 347 {
genesis 348 if (vInOutPoints.count(txin.prevout))
genesis 349 return false;
genesis 350 vInOutPoints.insert(txin.prevout);
genesis 351 }
genesis 352
genesis 353 if (IsCoinBase())
genesis 354 {
genesis 355 if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
genesis 356 return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
genesis 357 }
genesis 358 else
genesis 359 {
genesis 360 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 361 if (txin.prevout.IsNull())
genesis 362 return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
genesis 363 }
genesis 364
genesis 365 return true;
genesis 366 }
genesis 367
genesis 368 bool CTransaction::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs, bool* pfMissingInputs)
genesis 369 {
genesis 370 if (pfMissingInputs)
genesis 371 *pfMissingInputs = false;
genesis 372
genesis 373 if (!CheckTransaction())
genesis 374 return error("AcceptToMemoryPool() : CheckTransaction failed");
genesis 375
genesis 376
genesis 377 if (IsCoinBase())
genesis 378 return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
genesis 379
genesis 380
genesis 381 if ((int64)nLockTime > INT_MAX)
genesis 382 return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
genesis 383
genesis 384
genesis 385 unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
genesis 386
genesis 387
genesis 388
genesis 389
genesis 390 if (GetSigOpCount() > nSize / 34 || nSize < 100)
genesis 391 return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
genesis 392
genesis 393
genesis 394 if (!fTestNet && !IsStandard())
genesis 395 return error("AcceptToMemoryPool() : nonstandard transaction type");
genesis 396
genesis 397
genesis 398 uint256 hash = GetHash();
genesis 399 CRITICAL_BLOCK(cs_mapTransactions)
genesis 400 if (mapTransactions.count(hash))
genesis 401 return false;
genesis 402 if (fCheckInputs)
genesis 403 if (txdb.ContainsTx(hash))
genesis 404 return false;
genesis 405
genesis 406
genesis 407 CTransaction* ptxOld = NULL;
genesis 408 for (int i = 0; i < vin.size(); i++)
genesis 409 {
genesis 410 COutPoint outpoint = vin[i].prevout;
genesis 411 if (mapNextTx.count(outpoint))
genesis 412 {
genesis 413
genesis 414 return false;
genesis 415
genesis 416
genesis 417 if (i != 0)
genesis 418 return false;
genesis 419 ptxOld = mapNextTx[outpoint].ptx;
genesis 420 if (ptxOld->IsFinal())
genesis 421 return false;
genesis 422 if (!IsNewerThan(*ptxOld))
genesis 423 return false;
genesis 424 for (int i = 0; i < vin.size(); i++)
genesis 425 {
genesis 426 COutPoint outpoint = vin[i].prevout;
genesis 427 if (!mapNextTx.count(outpoint) || mapNextTx[outpoint].ptx != ptxOld)
genesis 428 return false;
genesis 429 }
genesis 430 break;
genesis 431 }
genesis 432 }
genesis 433
genesis 434 if (fCheckInputs)
genesis 435 {
genesis 436
genesis 437 map<uint256, CTxIndex> mapUnused;
genesis 438 int64 nFees = 0;
genesis 439 bool fInvalid = false;
genesis 440 if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
genesis 441 {
genesis 442 if (fInvalid)
genesis 443 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
genesis 444 return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
genesis 445 }
genesis 446
genesis 447
genesis 448 if (nFees < GetMinFee(1000, true, true))
genesis 449 return error("AcceptToMemoryPool() : not enough fees");
genesis 450
genesis 451
genesis 452
genesis 453
genesis 454 if (nFees < MIN_RELAY_TX_FEE)
genesis 455 {
genesis 456 static CCriticalSection cs;
genesis 457 static double dFreeCount;
genesis 458 static int64 nLastTime;
genesis 459 int64 nNow = GetTime();
genesis 460
genesis 461 CRITICAL_BLOCK(cs)
genesis 462 {
genesis 463
genesis 464 dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime));
genesis 465 nLastTime = nNow;
genesis 466
genesis 467
genesis 468 if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
genesis 469 return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
genesis 470 if (fDebug)
genesis 471 printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
genesis 472 dFreeCount += nSize;
genesis 473 }
genesis 474 }
genesis 475 }
genesis 476
genesis 477
genesis 478 CRITICAL_BLOCK(cs_mapTransactions)
genesis 479 {
genesis 480 if (ptxOld)
genesis 481 {
genesis 482 printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
genesis 483 ptxOld->RemoveFromMemoryPool();
genesis 484 }
genesis 485 AddToMemoryPoolUnchecked();
genesis 486 }
genesis 487
genesis 488
genesis 489
genesis 490 if (ptxOld)
genesis 491 EraseFromWallets(ptxOld->GetHash());
genesis 492
genesis 493 printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
genesis 494 return true;
genesis 495 }
genesis 496
genesis 497 bool CTransaction::AcceptToMemoryPool(bool fCheckInputs, bool* pfMissingInputs)
genesis 498 {
genesis 499 CTxDB txdb("r");
genesis 500 return AcceptToMemoryPool(txdb, fCheckInputs, pfMissingInputs);
genesis 501 }
genesis 502
genesis 503 bool CTransaction::AddToMemoryPoolUnchecked()
genesis 504 {
genesis 505
genesis 506
genesis 507 CRITICAL_BLOCK(cs_mapTransactions)
genesis 508 {
genesis 509 uint256 hash = GetHash();
genesis 510 mapTransactions[hash] = *this;
genesis 511 for (int i = 0; i < vin.size(); i++)
genesis 512 mapNextTx[vin[i].prevout] = CInPoint(&mapTransactions[hash], i);
genesis 513 nTransactionsUpdated++;
genesis 514 }
genesis 515 return true;
genesis 516 }
genesis 517
genesis 518
genesis 519 bool CTransaction::RemoveFromMemoryPool()
genesis 520 {
genesis 521
genesis 522 CRITICAL_BLOCK(cs_mapTransactions)
genesis 523 {
genesis 524 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 525 mapNextTx.erase(txin.prevout);
genesis 526 mapTransactions.erase(GetHash());
genesis 527 nTransactionsUpdated++;
genesis 528 }
genesis 529 return true;
genesis 530 }
genesis 531
genesis 532
genesis 533
genesis 534
genesis 535
genesis 536
genesis 537 int CMerkleTx::GetDepthInMainChain(int& nHeightRet) const
genesis 538 {
genesis 539 if (hashBlock == 0 || nIndex == -1)
genesis 540 return 0;
genesis 541
genesis 542
genesis 543 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock);
genesis 544 if (mi == mapBlockIndex.end())
genesis 545 return 0;
genesis 546 CBlockIndex* pindex = (*mi).second;
genesis 547 if (!pindex || !pindex->IsInMainChain())
genesis 548 return 0;
genesis 549
genesis 550
genesis 551 if (!fMerkleVerified)
genesis 552 {
genesis 553 if (CBlock::CheckMerkleBranch(GetHash(), vMerkleBranch, nIndex) != pindex->hashMerkleRoot)
genesis 554 return 0;
genesis 555 fMerkleVerified = true;
genesis 556 }
genesis 557
genesis 558 nHeightRet = pindex->nHeight;
genesis 559 return pindexBest->nHeight - pindex->nHeight + 1;
genesis 560 }
genesis 561
genesis 562
genesis 563 int CMerkleTx::GetBlocksToMaturity() const
genesis 564 {
genesis 565 if (!IsCoinBase())
genesis 566 return 0;
genesis 567 return max(0, (COINBASE_MATURITY+20) - GetDepthInMainChain());
genesis 568 }
genesis 569
genesis 570
genesis 571 bool CMerkleTx::AcceptToMemoryPool(CTxDB& txdb, bool fCheckInputs)
genesis 572 {
genesis 573 if (fClient)
genesis 574 {
genesis 575 if (!IsInMainChain() && !ClientConnectInputs())
genesis 576 return false;
genesis 577 return CTransaction::AcceptToMemoryPool(txdb, false);
genesis 578 }
genesis 579 else
genesis 580 {
genesis 581 return CTransaction::AcceptToMemoryPool(txdb, fCheckInputs);
genesis 582 }
genesis 583 }
genesis 584
genesis 585 bool CMerkleTx::AcceptToMemoryPool()
genesis 586 {
genesis 587 CTxDB txdb("r");
genesis 588 return AcceptToMemoryPool(txdb);
genesis 589 }
genesis 590
genesis 591
genesis 592
genesis 593 bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs)
genesis 594 {
genesis 595 CRITICAL_BLOCK(cs_mapTransactions)
genesis 596 {
genesis 597
genesis 598 BOOST_FOREACH(CMerkleTx& tx, vtxPrev)
genesis 599 {
genesis 600 if (!tx.IsCoinBase())
genesis 601 {
genesis 602 uint256 hash = tx.GetHash();
genesis 603 if (!mapTransactions.count(hash) && !txdb.ContainsTx(hash))
genesis 604 tx.AcceptToMemoryPool(txdb, fCheckInputs);
genesis 605 }
genesis 606 }
genesis 607 return AcceptToMemoryPool(txdb, fCheckInputs);
genesis 608 }
genesis 609 return false;
genesis 610 }
genesis 611
genesis 612 bool CWalletTx::AcceptWalletTransaction()
genesis 613 {
genesis 614 CTxDB txdb("r");
genesis 615 return AcceptWalletTransaction(txdb);
genesis 616 }
genesis 617
genesis 618 int CTxIndex::GetDepthInMainChain() const
genesis 619 {
genesis 620
genesis 621 CBlock block;
genesis 622 if (!block.ReadFromDisk(pos.nFile, pos.nBlockPos, false))
genesis 623 return 0;
genesis 624
genesis 625 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.GetHash());
genesis 626 if (mi == mapBlockIndex.end())
genesis 627 return 0;
genesis 628 CBlockIndex* pindex = (*mi).second;
genesis 629 if (!pindex || !pindex->IsInMainChain())
genesis 630 return 0;
genesis 631 return 1 + nBestHeight - pindex->nHeight;
genesis 632 }
genesis 633
genesis 634
genesis 635
genesis 636
genesis 637
genesis 638
genesis 639
genesis 640
genesis 641
genesis 642
genesis 643
genesis 644
genesis 645
genesis 646
genesis 647
genesis 648 bool CBlock::ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions)
genesis 649 {
genesis 650 if (!fReadTransactions)
genesis 651 {
genesis 652 *this = pindex->GetBlockHeader();
genesis 653 return true;
genesis 654 }
genesis 655 if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
genesis 656 return false;
genesis 657 if (GetHash() != pindex->GetBlockHash())
genesis 658 return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
genesis 659 return true;
genesis 660 }
genesis 661
genesis 662 uint256 static GetOrphanRoot(const CBlock* pblock)
genesis 663 {
genesis 664
genesis 665 while (mapOrphanBlocks.count(pblock->hashPrevBlock))
genesis 666 pblock = mapOrphanBlocks[pblock->hashPrevBlock];
genesis 667 return pblock->GetHash();
genesis 668 }
genesis 669
genesis 670 int64 static GetBlockValue(int nHeight, int64 nFees)
genesis 671 {
genesis 672 int64 nSubsidy = 50 * COIN;
genesis 673
genesis 674
genesis 675 nSubsidy >>= (nHeight / 210000);
genesis 676
genesis 677 return nSubsidy + nFees;
genesis 678 }
genesis 679
genesis 680 static const int64 nTargetTimespan = 14 * 24 * 60 * 60;
genesis 681 static const int64 nTargetSpacing = 10 * 60;
genesis 682 static const int64 nInterval = nTargetTimespan / nTargetSpacing;
genesis 683
genesis 684
genesis 685
genesis 686
genesis 687
genesis 688 unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
genesis 689 {
genesis 690
genesis 691
genesis 692 if (fTestNet && nTime > nTargetSpacing*2)
genesis 693 return bnProofOfWorkLimit.GetCompact();
genesis 694
genesis 695 CBigNum bnResult;
genesis 696 bnResult.SetCompact(nBase);
genesis 697 while (nTime > 0 && bnResult < bnProofOfWorkLimit)
genesis 698 {
genesis 699
genesis 700 bnResult *= 4;
genesis 701
genesis 702 nTime -= nTargetTimespan*4;
genesis 703 }
genesis 704 if (bnResult > bnProofOfWorkLimit)
genesis 705 bnResult = bnProofOfWorkLimit;
genesis 706 return bnResult.GetCompact();
genesis 707 }
genesis 708
genesis 709 unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlock *pblock)
genesis 710 {
genesis 711 unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();
genesis 712
genesis 713
genesis 714 if (pindexLast == NULL)
genesis 715 return nProofOfWorkLimit;
genesis 716
genesis 717
genesis 718 if ((pindexLast->nHeight+1) % nInterval != 0)
genesis 719 {
genesis 720
genesis 721 if (fTestNet && pblock->nTime > 1329264000)
genesis 722 {
genesis 723
genesis 724
genesis 725 if (pblock->nTime - pindexLast->nTime > nTargetSpacing*2)
genesis 726 return nProofOfWorkLimit;
genesis 727 else
genesis 728 {
genesis 729
genesis 730 const CBlockIndex* pindex = pindexLast;
genesis 731 while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
genesis 732 pindex = pindex->pprev;
genesis 733 return pindex->nBits;
genesis 734 }
genesis 735 }
genesis 736
genesis 737 return pindexLast->nBits;
genesis 738 }
genesis 739
genesis 740
genesis 741 const CBlockIndex* pindexFirst = pindexLast;
genesis 742 for (int i = 0; pindexFirst && i < nInterval-1; i++)
genesis 743 pindexFirst = pindexFirst->pprev;
genesis 744 assert(pindexFirst);
genesis 745
genesis 746
genesis 747 int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
genesis 748 printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
genesis 749 if (nActualTimespan < nTargetTimespan/4)
genesis 750 nActualTimespan = nTargetTimespan/4;
genesis 751 if (nActualTimespan > nTargetTimespan*4)
genesis 752 nActualTimespan = nTargetTimespan*4;
genesis 753
genesis 754
genesis 755 CBigNum bnNew;
genesis 756 bnNew.SetCompact(pindexLast->nBits);
genesis 757 bnNew *= nActualTimespan;
genesis 758 bnNew /= nTargetTimespan;
genesis 759
genesis 760 if (bnNew > bnProofOfWorkLimit)
genesis 761 bnNew = bnProofOfWorkLimit;
genesis 762
genesis 763
genesis 764 printf("GetNextWorkRequired RETARGET\n");
genesis 765 printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
genesis 766 printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
genesis 767 printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
genesis 768
genesis 769 return bnNew.GetCompact();
genesis 770 }
genesis 771
genesis 772 bool CheckProofOfWork(uint256 hash, unsigned int nBits)
genesis 773 {
genesis 774 CBigNum bnTarget;
genesis 775 bnTarget.SetCompact(nBits);
genesis 776
genesis 777
genesis 778 if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
genesis 779 return error("CheckProofOfWork() : nBits below minimum work");
genesis 780
genesis 781
genesis 782 if (hash > bnTarget.getuint256())
genesis 783 return error("CheckProofOfWork() : hash doesn't match nBits");
genesis 784
genesis 785 return true;
genesis 786 }
genesis 787
genesis 788
genesis 789 int GetNumBlocksOfPeers()
genesis 790 {
genesis 791 return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
genesis 792 }
genesis 793
genesis 794 bool IsInitialBlockDownload()
genesis 795 {
genesis 796 if (pindexBest == NULL || nBestHeight < Checkpoints::GetTotalBlocksEstimate())
genesis 797 return true;
genesis 798 static int64 nLastUpdate;
genesis 799 static CBlockIndex* pindexLastBest;
genesis 800 if (pindexBest != pindexLastBest)
genesis 801 {
genesis 802 pindexLastBest = pindexBest;
genesis 803 nLastUpdate = GetTime();
genesis 804 }
genesis 805 return (GetTime() - nLastUpdate < 10 &&
genesis 806 pindexBest->GetBlockTime() < GetTime() - 24 * 60 * 60);
genesis 807 }
genesis 808
genesis 809 void static InvalidChainFound(CBlockIndex* pindexNew)
genesis 810 {
genesis 811 if (pindexNew->bnChainWork > bnBestInvalidWork)
genesis 812 {
genesis 813 bnBestInvalidWork = pindexNew->bnChainWork;
genesis 814 CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
genesis 815 MainFrameRepaint();
genesis 816 }
genesis 817 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());
genesis 818 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
genesis 819 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
genesis 820 printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
genesis 821 }
genesis 822
genesis 823
genesis 824
genesis 825
genesis 826
genesis 827
genesis 828
genesis 829
genesis 830
genesis 831
genesis 832
genesis 833 bool CTransaction::DisconnectInputs(CTxDB& txdb)
genesis 834 {
genesis 835
genesis 836 if (!IsCoinBase())
genesis 837 {
genesis 838 BOOST_FOREACH(const CTxIn& txin, vin)
genesis 839 {
genesis 840 COutPoint prevout = txin.prevout;
genesis 841
genesis 842
genesis 843 CTxIndex txindex;
genesis 844 if (!txdb.ReadTxIndex(prevout.hash, txindex))
genesis 845 return error("DisconnectInputs() : ReadTxIndex failed");
genesis 846
genesis 847 if (prevout.n >= txindex.vSpent.size())
genesis 848 return error("DisconnectInputs() : prevout.n out of range");
genesis 849
genesis 850
genesis 851 txindex.vSpent[prevout.n].SetNull();
genesis 852
genesis 853
genesis 854 if (!txdb.UpdateTxIndex(prevout.hash, txindex))
genesis 855 return error("DisconnectInputs() : UpdateTxIndex failed");
genesis 856 }
genesis 857 }
genesis 858
genesis 859
genesis 860
genesis 861
genesis 862
genesis 863 txdb.EraseTxIndex(*this);
genesis 864
genesis 865 return true;
genesis 866 }
genesis 867
genesis 868
genesis 869 bool CTransaction::ConnectInputs(CTxDB& txdb, map<uint256, CTxIndex>& mapTestPool, CDiskTxPos posThisTx,
genesis 870 CBlockIndex* pindexBlock, int64& nFees, bool fBlock, bool fMiner, int64 nMinFee,
genesis 871 bool& fInvalid)
genesis 872 {
genesis 873
genesis 874
genesis 875
genesis 876
genesis 877 fInvalid = false;
genesis 878
genesis 879
genesis 880
genesis 881
genesis 882
genesis 883 if (!IsCoinBase())
genesis 884 {
genesis 885 int64 nValueIn = 0;
genesis 886 for (int i = 0; i < vin.size(); i++)
genesis 887 {
genesis 888 COutPoint prevout = vin[i].prevout;
genesis 889
genesis 890
genesis 891 CTxIndex txindex;
genesis 892 bool fFound = true;
genesis 893 if ((fBlock || fMiner) && mapTestPool.count(prevout.hash))
genesis 894 {
genesis 895
genesis 896 txindex = mapTestPool[prevout.hash];
genesis 897 }
genesis 898 else
genesis 899 {
genesis 900
genesis 901 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
genesis 902 }
genesis 903 if (!fFound && (fBlock || fMiner))
genesis 904 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
genesis 905
genesis 906
genesis 907 CTransaction txPrev;
genesis 908 if (!fFound || txindex.pos == CDiskTxPos(1,1,1))
genesis 909 {
genesis 910
genesis 911 CRITICAL_BLOCK(cs_mapTransactions)
genesis 912 {
genesis 913 if (!mapTransactions.count(prevout.hash))
genesis 914 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
genesis 915 txPrev = mapTransactions[prevout.hash];
genesis 916 }
genesis 917 if (!fFound)
genesis 918 txindex.vSpent.resize(txPrev.vout.size());
genesis 919 }
genesis 920 else
genesis 921 {
genesis 922
genesis 923 if (!txPrev.ReadFromDisk(txindex.pos))
genesis 924 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
genesis 925 }
genesis 926
genesis 927 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
genesis 928 {
genesis 929
genesis 930
genesis 931 fInvalid = true;
genesis 932 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
genesis 933 }
genesis 934
genesis 935
genesis 936 if (txPrev.IsCoinBase())
genesis 937 for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
genesis 938 if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
genesis 939 return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
genesis 940
genesis 941
genesis 942
genesis 943
genesis 944 if (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate())))
genesis 945
genesis 946 if (!VerifySignature(txPrev, *this, i))
genesis 947 return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
genesis 948
genesis 949
genesis 950
genesis 951
genesis 952 if (!txindex.vSpent[prevout.n].IsNull())
genesis 953 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
genesis 954
genesis 955
genesis 956 nValueIn += txPrev.vout[prevout.n].nValue;
genesis 957 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
genesis 958 return DoS(100, error("ConnectInputs() : txin values out of range"));
genesis 959
genesis 960
genesis 961 txindex.vSpent[prevout.n] = posThisTx;
genesis 962
genesis 963
genesis 964 if (fBlock || fMiner)
genesis 965 {
genesis 966 mapTestPool[prevout.hash] = txindex;
genesis 967 }
genesis 968 }
genesis 969
genesis 970 if (nValueIn < GetValueOut())
genesis 971 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
genesis 972
genesis 973
genesis 974 int64 nTxFee = nValueIn - GetValueOut();
genesis 975 if (nTxFee < 0)
genesis 976 return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
genesis 977 if (nTxFee < nMinFee)
genesis 978 return false;
genesis 979 nFees += nTxFee;
genesis 980 if (!MoneyRange(nFees))
genesis 981 return DoS(100, error("ConnectInputs() : nFees out of range"));
genesis 982 }
genesis 983
genesis 984 if (fBlock)
genesis 985 {
genesis 986
genesis 987 mapTestPool[GetHash()] = CTxIndex(posThisTx, vout.size());
genesis 988 }
genesis 989 else if (fMiner)
genesis 990 {
genesis 991
genesis 992 mapTestPool[GetHash()] = CTxIndex(CDiskTxPos(1,1,1), vout.size());
genesis 993 }
genesis 994
genesis 995 return true;
genesis 996 }
genesis 997
genesis 998
genesis 999 bool CTransaction::ClientConnectInputs()
genesis 1000 {
genesis 1001 if (IsCoinBase())
genesis 1002 return false;
genesis 1003
genesis 1004
genesis 1005 CRITICAL_BLOCK(cs_mapTransactions)
genesis 1006 {
genesis 1007 int64 nValueIn = 0;
genesis 1008 for (int i = 0; i < vin.size(); i++)
genesis 1009 {
genesis 1010
genesis 1011 COutPoint prevout = vin[i].prevout;
genesis 1012 if (!mapTransactions.count(prevout.hash))
genesis 1013 return false;
genesis 1014 CTransaction& txPrev = mapTransactions[prevout.hash];
genesis 1015
genesis 1016 if (prevout.n >= txPrev.vout.size())
genesis 1017 return false;
genesis 1018
genesis 1019
genesis 1020 if (!VerifySignature(txPrev, *this, i))
genesis 1021 return error("ConnectInputs() : VerifySignature failed");
genesis 1022
genesis 1023
genesis 1024
genesis 1025
genesis 1026
genesis 1027
genesis 1028
genesis 1029
genesis 1030
genesis 1031
genesis 1032 nValueIn += txPrev.vout[prevout.n].nValue;
genesis 1033
genesis 1034 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
genesis 1035 return error("ClientConnectInputs() : txin values out of range");
genesis 1036 }
genesis 1037 if (GetValueOut() > nValueIn)
genesis 1038 return false;
genesis 1039 }
genesis 1040
genesis 1041 return true;
genesis 1042 }
genesis 1043
genesis 1044
genesis 1045
genesis 1046
genesis 1047 bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex)
genesis 1048 {
genesis 1049
genesis 1050 for (int i = vtx.size()-1; i >= 0; i--)
genesis 1051 if (!vtx[i].DisconnectInputs(txdb))
genesis 1052 return false;
genesis 1053
genesis 1054
genesis 1055
genesis 1056 if (pindex->pprev)
genesis 1057 {
genesis 1058 CDiskBlockIndex blockindexPrev(pindex->pprev);
genesis 1059 blockindexPrev.hashNext = 0;
genesis 1060 if (!txdb.WriteBlockIndex(blockindexPrev))
genesis 1061 return error("DisconnectBlock() : WriteBlockIndex failed");
genesis 1062 }
genesis 1063
genesis 1064 return true;
genesis 1065 }
genesis 1066
genesis 1067 bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex)
genesis 1068 {
genesis 1069
genesis 1070 if (!CheckBlock())
genesis 1071 return false;
genesis 1072
genesis 1073
genesis 1074
genesis 1075
genesis 1076
genesis 1077
genesis 1078
genesis 1079
genesis 1080
genesis 1081
genesis 1082
genesis 1083 if (pindex->nTime > 1331769600 || (fTestNet && pindex->nTime > 1329696000))
genesis 1084 BOOST_FOREACH(CTransaction& tx, vtx)
genesis 1085 {
genesis 1086 CTxIndex txindexOld;
genesis 1087 if (txdb.ReadTxIndex(tx.GetHash(), txindexOld))
genesis 1088 BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent)
genesis 1089 if (pos.IsNull())
genesis 1090 return false;
genesis 1091 }
genesis 1092
genesis 1093
genesis 1094 unsigned int nTxPos = pindex->nBlockPos + ::GetSerializeSize(CBlock(), SER_DISK) - 1 + GetSizeOfCompactSize(vtx.size());
genesis 1095
genesis 1096 map<uint256, CTxIndex> mapQueuedChanges;
genesis 1097 int64 nFees = 0;
genesis 1098 BOOST_FOREACH(CTransaction& tx, vtx)
genesis 1099 {
genesis 1100 CDiskTxPos posThisTx(pindex->nFile, pindex->nBlockPos, nTxPos);
genesis 1101 nTxPos += ::GetSerializeSize(tx, SER_DISK);
genesis 1102
genesis 1103 bool fInvalid;
genesis 1104 if (!tx.ConnectInputs(txdb, mapQueuedChanges, posThisTx, pindex, nFees, true, false, 0, fInvalid))
genesis 1105 return false;
genesis 1106 }
genesis 1107
genesis 1108 for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
genesis 1109 {
genesis 1110 if (!txdb.UpdateTxIndex((*mi).first, (*mi).second))
genesis 1111 return error("ConnectBlock() : UpdateTxIndex failed");
genesis 1112 }
genesis 1113
genesis 1114 if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
genesis 1115 return false;
genesis 1116
genesis 1117
genesis 1118
genesis 1119 if (pindex->pprev)
genesis 1120 {
genesis 1121 CDiskBlockIndex blockindexPrev(pindex->pprev);
genesis 1122 blockindexPrev.hashNext = pindex->GetBlockHash();
genesis 1123 if (!txdb.WriteBlockIndex(blockindexPrev))
genesis 1124 return error("ConnectBlock() : WriteBlockIndex failed");
genesis 1125 }
genesis 1126
genesis 1127
genesis 1128 BOOST_FOREACH(CTransaction& tx, vtx)
genesis 1129 SyncWithWallets(tx, this, true);
genesis 1130
genesis 1131 return true;
genesis 1132 }
genesis 1133
genesis 1134 bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
genesis 1135 {
genesis 1136 printf("REORGANIZE\n");
genesis 1137
genesis 1138
genesis 1139 CBlockIndex* pfork = pindexBest;
genesis 1140 CBlockIndex* plonger = pindexNew;
genesis 1141 while (pfork != plonger)
genesis 1142 {
genesis 1143 while (plonger->nHeight > pfork->nHeight)
genesis 1144 if (!(plonger = plonger->pprev))
genesis 1145 return error("Reorganize() : plonger->pprev is null");
genesis 1146 if (pfork == plonger)
genesis 1147 break;
genesis 1148 if (!(pfork = pfork->pprev))
genesis 1149 return error("Reorganize() : pfork->pprev is null");
genesis 1150 }
genesis 1151
genesis 1152
genesis 1153 vector<CBlockIndex*> vDisconnect;
genesis 1154 for (CBlockIndex* pindex = pindexBest; pindex != pfork; pindex = pindex->pprev)
genesis 1155 vDisconnect.push_back(pindex);
genesis 1156
genesis 1157
genesis 1158 vector<CBlockIndex*> vConnect;
genesis 1159 for (CBlockIndex* pindex = pindexNew; pindex != pfork; pindex = pindex->pprev)
genesis 1160 vConnect.push_back(pindex);
genesis 1161 reverse(vConnect.begin(), vConnect.end());
genesis 1162
genesis 1163
genesis 1164 vector<CTransaction> vResurrect;
genesis 1165 BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
genesis 1166 {
genesis 1167 CBlock block;
genesis 1168 if (!block.ReadFromDisk(pindex))
genesis 1169 return error("Reorganize() : ReadFromDisk for disconnect failed");
genesis 1170 if (!block.DisconnectBlock(txdb, pindex))
genesis 1171 return error("Reorganize() : DisconnectBlock failed");
genesis 1172
genesis 1173
genesis 1174 BOOST_FOREACH(const CTransaction& tx, block.vtx)
genesis 1175 if (!tx.IsCoinBase())
genesis 1176 vResurrect.push_back(tx);
genesis 1177 }
genesis 1178
genesis 1179
genesis 1180 vector<CTransaction> vDelete;
genesis 1181 for (int i = 0; i < vConnect.size(); i++)
genesis 1182 {
genesis 1183 CBlockIndex* pindex = vConnect[i];
genesis 1184 CBlock block;
genesis 1185 if (!block.ReadFromDisk(pindex))
genesis 1186 return error("Reorganize() : ReadFromDisk for connect failed");
genesis 1187 if (!block.ConnectBlock(txdb, pindex))
genesis 1188 {
genesis 1189
genesis 1190 txdb.TxnAbort();
genesis 1191 return error("Reorganize() : ConnectBlock failed");
genesis 1192 }
genesis 1193
genesis 1194
genesis 1195 BOOST_FOREACH(const CTransaction& tx, block.vtx)
genesis 1196 vDelete.push_back(tx);
genesis 1197 }
genesis 1198 if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
genesis 1199 return error("Reorganize() : WriteHashBestChain failed");
genesis 1200
genesis 1201
genesis 1202 if (!txdb.TxnCommit())
genesis 1203 return error("Reorganize() : TxnCommit failed");
genesis 1204
genesis 1205
genesis 1206 BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
genesis 1207 if (pindex->pprev)
genesis 1208 pindex->pprev->pnext = NULL;
genesis 1209
genesis 1210
genesis 1211 BOOST_FOREACH(CBlockIndex* pindex, vConnect)
genesis 1212 if (pindex->pprev)
genesis 1213 pindex->pprev->pnext = pindex;
genesis 1214
genesis 1215
genesis 1216 BOOST_FOREACH(CTransaction& tx, vResurrect)
genesis 1217 tx.AcceptToMemoryPool(txdb, false);
genesis 1218
genesis 1219
genesis 1220 BOOST_FOREACH(CTransaction& tx, vDelete)
genesis 1221 tx.RemoveFromMemoryPool();
genesis 1222
genesis 1223 return true;
genesis 1224 }
genesis 1225
genesis 1226
genesis 1227 bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
genesis 1228 {
genesis 1229 uint256 hash = GetHash();
genesis 1230
genesis 1231 txdb.TxnBegin();
genesis 1232 if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
genesis 1233 {
genesis 1234 txdb.WriteHashBestChain(hash);
genesis 1235 if (!txdb.TxnCommit())
genesis 1236 return error("SetBestChain() : TxnCommit failed");
genesis 1237 pindexGenesisBlock = pindexNew;
genesis 1238 }
genesis 1239 else if (hashPrevBlock == hashBestChain)
genesis 1240 {
genesis 1241
genesis 1242 if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
genesis 1243 {
genesis 1244 txdb.TxnAbort();
genesis 1245 InvalidChainFound(pindexNew);
genesis 1246 return error("SetBestChain() : ConnectBlock failed");
genesis 1247 }
genesis 1248 if (!txdb.TxnCommit())
genesis 1249 return error("SetBestChain() : TxnCommit failed");
genesis 1250
genesis 1251
genesis 1252 pindexNew->pprev->pnext = pindexNew;
genesis 1253
genesis 1254
genesis 1255 BOOST_FOREACH(CTransaction& tx, vtx)
genesis 1256 tx.RemoveFromMemoryPool();
genesis 1257 }
genesis 1258 else
genesis 1259 {
genesis 1260
genesis 1261 if (!Reorganize(txdb, pindexNew))
genesis 1262 {
genesis 1263 txdb.TxnAbort();
genesis 1264 InvalidChainFound(pindexNew);
genesis 1265 return error("SetBestChain() : Reorganize failed");
genesis 1266 }
genesis 1267 }
genesis 1268
genesis 1269
genesis 1270 if (!IsInitialBlockDownload())
genesis 1271 {
genesis 1272 const CBlockLocator locator(pindexNew);
genesis 1273 ::SetBestChain(locator);
genesis 1274 }
genesis 1275
genesis 1276
genesis 1277 hashBestChain = hash;
genesis 1278 pindexBest = pindexNew;
genesis 1279 nBestHeight = pindexBest->nHeight;
genesis 1280 bnBestChainWork = pindexNew->bnChainWork;
genesis 1281 nTimeBestReceived = GetTime();
genesis 1282 nTransactionsUpdated++;
genesis 1283 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
genesis 1284
genesis 1285 return true;
genesis 1286 }
genesis 1287
genesis 1288
genesis 1289 bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
genesis 1290 {
genesis 1291
genesis 1292 uint256 hash = GetHash();
genesis 1293 if (mapBlockIndex.count(hash))
genesis 1294 return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
genesis 1295
genesis 1296
genesis 1297 CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
genesis 1298 if (!pindexNew)
genesis 1299 return error("AddToBlockIndex() : new CBlockIndex failed");
genesis 1300 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
genesis 1301 pindexNew->phashBlock = &((*mi).first);
genesis 1302 map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
genesis 1303 if (miPrev != mapBlockIndex.end())
genesis 1304 {
genesis 1305 pindexNew->pprev = (*miPrev).second;
genesis 1306 pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
genesis 1307 }
genesis 1308 pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
genesis 1309
genesis 1310 CTxDB txdb;
genesis 1311 txdb.TxnBegin();
genesis 1312 txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
genesis 1313 if (!txdb.TxnCommit())
genesis 1314 return false;
genesis 1315
genesis 1316
genesis 1317 if (pindexNew->bnChainWork > bnBestChainWork)
genesis 1318 if (!SetBestChain(txdb, pindexNew))
genesis 1319 return false;
genesis 1320
genesis 1321 txdb.Close();
genesis 1322
genesis 1323 if (pindexNew == pindexBest)
genesis 1324 {
genesis 1325
genesis 1326 static uint256 hashPrevBestCoinBase;
genesis 1327 UpdatedTransaction(hashPrevBestCoinBase);
genesis 1328 hashPrevBestCoinBase = vtx[0].GetHash();
genesis 1329 }
genesis 1330
genesis 1331 MainFrameRepaint();
genesis 1332 return true;
genesis 1333 }
genesis 1334
genesis 1335
genesis 1336
genesis 1337
genesis 1338 bool CBlock::CheckBlock() const
genesis 1339 {
genesis 1340
genesis 1341
genesis 1342
genesis 1343
genesis 1344 if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
genesis 1345 return DoS(100, error("CheckBlock() : size limits failed"));
genesis 1346
genesis 1347
genesis 1348 if (!CheckProofOfWork(GetHash(), nBits))
genesis 1349 return DoS(50, error("CheckBlock() : proof of work failed"));
genesis 1350
genesis 1351
genesis 1352 if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
genesis 1353 return error("CheckBlock() : block timestamp too far in the future");
genesis 1354
genesis 1355
genesis 1356 if (vtx.empty() || !vtx[0].IsCoinBase())
genesis 1357 return DoS(100, error("CheckBlock() : first tx is not coinbase"));
genesis 1358 for (int i = 1; i < vtx.size(); i++)
genesis 1359 if (vtx[i].IsCoinBase())
genesis 1360 return DoS(100, error("CheckBlock() : more than one coinbase"));
genesis 1361
genesis 1362
genesis 1363 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 1364 if (!tx.CheckTransaction())
genesis 1365 return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
genesis 1366
genesis 1367
genesis 1368 if (GetSigOpCount() > MAX_BLOCK_SIGOPS)
genesis 1369 return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
genesis 1370
genesis 1371
genesis 1372 if (hashMerkleRoot != BuildMerkleTree())
genesis 1373 return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
genesis 1374
genesis 1375 return true;
genesis 1376 }
genesis 1377
genesis 1378 bool CBlock::AcceptBlock()
genesis 1379 {
genesis 1380
genesis 1381 uint256 hash = GetHash();
genesis 1382 if (mapBlockIndex.count(hash))
genesis 1383 return error("AcceptBlock() : block already in mapBlockIndex");
genesis 1384
genesis 1385
genesis 1386 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
genesis 1387 if (mi == mapBlockIndex.end())
genesis 1388 return DoS(10, error("AcceptBlock() : prev block not found"));
genesis 1389 CBlockIndex* pindexPrev = (*mi).second;
genesis 1390 int nHeight = pindexPrev->nHeight+1;
genesis 1391
genesis 1392
genesis 1393 if (nBits != GetNextWorkRequired(pindexPrev, this))
genesis 1394 return DoS(100, error("AcceptBlock() : incorrect proof of work"));
genesis 1395
genesis 1396
genesis 1397 if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
genesis 1398 return error("AcceptBlock() : block's timestamp is too early");
genesis 1399
genesis 1400
genesis 1401 BOOST_FOREACH(const CTransaction& tx, vtx)
genesis 1402 if (!tx.IsFinal(nHeight, GetBlockTime()))
genesis 1403 return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
genesis 1404
genesis 1405
genesis 1406 if (!Checkpoints::CheckBlock(nHeight, hash))
genesis 1407 return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
genesis 1408
genesis 1409
genesis 1410 if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
genesis 1411 return error("AcceptBlock() : out of disk space");
genesis 1412 unsigned int nFile = -1;
genesis 1413 unsigned int nBlockPos = 0;
genesis 1414 if (!WriteToDisk(nFile, nBlockPos))
genesis 1415 return error("AcceptBlock() : WriteToDisk failed");
genesis 1416 if (!AddToBlockIndex(nFile, nBlockPos))
genesis 1417 return error("AcceptBlock() : AddToBlockIndex failed");
genesis 1418
genesis 1419
genesis 1420 if (hashBestChain == hash)
genesis 1421 CRITICAL_BLOCK(cs_vNodes)
genesis 1422 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 1423 if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 140700))
genesis 1424 pnode->PushInventory(CInv(MSG_BLOCK, hash));
genesis 1425
genesis 1426 return true;
genesis 1427 }
genesis 1428
genesis 1429 bool ProcessBlock(CNode* pfrom, CBlock* pblock)
genesis 1430 {
genesis 1431
genesis 1432 uint256 hash = pblock->GetHash();
genesis 1433 if (mapBlockIndex.count(hash))
genesis 1434 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
genesis 1435 if (mapOrphanBlocks.count(hash))
genesis 1436 return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());
genesis 1437
genesis 1438
genesis 1439 if (!pblock->CheckBlock())
genesis 1440 return error("ProcessBlock() : CheckBlock FAILED");
genesis 1441
genesis 1442 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
genesis 1443 if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
genesis 1444 {
genesis 1445
genesis 1446 int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
genesis 1447 if (deltaTime < 0)
genesis 1448 {
genesis 1449 if (pfrom)
genesis 1450 pfrom->Misbehaving(100);
genesis 1451 return error("ProcessBlock() : block with timestamp before last checkpoint");
genesis 1452 }
genesis 1453 CBigNum bnNewBlock;
genesis 1454 bnNewBlock.SetCompact(pblock->nBits);
genesis 1455 CBigNum bnRequired;
genesis 1456 bnRequired.SetCompact(ComputeMinWork(pcheckpoint->nBits, deltaTime));
genesis 1457 if (bnNewBlock > bnRequired)
genesis 1458 {
genesis 1459 if (pfrom)
genesis 1460 pfrom->Misbehaving(100);
genesis 1461 return error("ProcessBlock() : block with too little proof-of-work");
genesis 1462 }
genesis 1463 }
genesis 1464
genesis 1465
genesis 1466
genesis 1467 if (!mapBlockIndex.count(pblock->hashPrevBlock))
genesis 1468 {
genesis 1469 printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
genesis 1470 CBlock* pblock2 = new CBlock(*pblock);
genesis 1471 mapOrphanBlocks.insert(make_pair(hash, pblock2));
genesis 1472 mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));
genesis 1473
genesis 1474
genesis 1475 if (pfrom)
genesis 1476 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
genesis 1477 return true;
genesis 1478 }
genesis 1479
genesis 1480
genesis 1481 if (!pblock->AcceptBlock())
genesis 1482 return error("ProcessBlock() : AcceptBlock FAILED");
genesis 1483
genesis 1484
genesis 1485 vector<uint256> vWorkQueue;
genesis 1486 vWorkQueue.push_back(hash);
genesis 1487 for (int i = 0; i < vWorkQueue.size(); i++)
genesis 1488 {
genesis 1489 uint256 hashPrev = vWorkQueue[i];
genesis 1490 for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
genesis 1491 mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
genesis 1492 ++mi)
genesis 1493 {
genesis 1494 CBlock* pblockOrphan = (*mi).second;
genesis 1495 if (pblockOrphan->AcceptBlock())
genesis 1496 vWorkQueue.push_back(pblockOrphan->GetHash());
genesis 1497 mapOrphanBlocks.erase(pblockOrphan->GetHash());
genesis 1498 delete pblockOrphan;
genesis 1499 }
genesis 1500 mapOrphanBlocksByPrev.erase(hashPrev);
genesis 1501 }
genesis 1502
genesis 1503 printf("ProcessBlock: ACCEPTED\n");
genesis 1504 return true;
genesis 1505 }
genesis 1506
genesis 1507
genesis 1508
genesis 1509
genesis 1510
genesis 1511
genesis 1512
genesis 1513
genesis 1514 bool CheckDiskSpace(uint64 nAdditionalBytes)
genesis 1515 {
genesis 1516 uint64 nFreeBytesAvailable = filesystem::space(GetDataDir()).available;
genesis 1517
genesis 1518
genesis 1519 if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
genesis 1520 {
genesis 1521 fShutdown = true;
genesis 1522 string strMessage = _("Warning: Disk space is low ");
genesis 1523 strMiscWarning = strMessage;
genesis 1524 printf("*** %s\n", strMessage.c_str());
genesis 1525 ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
genesis 1526 CreateThread(Shutdown, NULL);
genesis 1527 return false;
genesis 1528 }
genesis 1529 return true;
genesis 1530 }
genesis 1531
genesis 1532 FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode)
genesis 1533 {
genesis 1534 if (nFile == -1)
genesis 1535 return NULL;
genesis 1536 FILE* file = fopen(strprintf("%s/blk%04d.dat", GetDataDir().c_str(), nFile).c_str(), pszMode);
genesis 1537 if (!file)
genesis 1538 return NULL;
genesis 1539 if (nBlockPos != 0 && !strchr(pszMode, 'a') && !strchr(pszMode, 'w'))
genesis 1540 {
genesis 1541 if (fseek(file, nBlockPos, SEEK_SET) != 0)
genesis 1542 {
genesis 1543 fclose(file);
genesis 1544 return NULL;
genesis 1545 }
genesis 1546 }
genesis 1547 return file;
genesis 1548 }
genesis 1549
genesis 1550 static unsigned int nCurrentBlockFile = 1;
genesis 1551
genesis 1552 FILE* AppendBlockFile(unsigned int& nFileRet)
genesis 1553 {
genesis 1554 nFileRet = 0;
genesis 1555 loop
genesis 1556 {
genesis 1557 FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab");
genesis 1558 if (!file)
genesis 1559 return NULL;
genesis 1560 if (fseek(file, 0, SEEK_END) != 0)
genesis 1561 return NULL;
genesis 1562
genesis 1563 if (ftell(file) < 0x7F000000 - MAX_SIZE)
genesis 1564 {
genesis 1565 nFileRet = nCurrentBlockFile;
genesis 1566 return file;
genesis 1567 }
genesis 1568 fclose(file);
genesis 1569 nCurrentBlockFile++;
genesis 1570 }
genesis 1571 }
genesis 1572
genesis 1573 bool LoadBlockIndex(bool fAllowNew)
genesis 1574 {
genesis 1575 if (fTestNet)
genesis 1576 {
genesis 1577 hashGenesisBlock = uint256("0x00000007199508e34a9ff81e6ec0c477a4cccff2a4767a8eee39c11db367b008");
genesis 1578 bnProofOfWorkLimit = CBigNum(~uint256(0) >> 28);
genesis 1579 pchMessageStart[0] = 0xfa;
genesis 1580 pchMessageStart[1] = 0xbf;
genesis 1581 pchMessageStart[2] = 0xb5;
genesis 1582 pchMessageStart[3] = 0xda;
genesis 1583 }
genesis 1584
genesis 1585
genesis 1586
genesis 1587
genesis 1588 CTxDB txdb("cr");
genesis 1589 if (!txdb.LoadBlockIndex())
genesis 1590 return false;
genesis 1591 txdb.Close();
genesis 1592
genesis 1593
genesis 1594
genesis 1595
genesis 1596 if (mapBlockIndex.empty())
genesis 1597 {
genesis 1598 if (!fAllowNew)
genesis 1599 return false;
genesis 1600
genesis 1601
genesis 1602
genesis 1603
genesis 1604
genesis 1605
genesis 1606
genesis 1607
genesis 1608
genesis 1609 const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
genesis 1610 CTransaction txNew;
genesis 1611 txNew.vin.resize(1);
genesis 1612 txNew.vout.resize(1);
genesis 1613 txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
genesis 1614 txNew.vout[0].nValue = 50 * COIN;
genesis 1615 txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG;
genesis 1616 CBlock block;
genesis 1617 block.vtx.push_back(txNew);
genesis 1618 block.hashPrevBlock = 0;
genesis 1619 block.hashMerkleRoot = block.BuildMerkleTree();
genesis 1620 block.nVersion = 1;
genesis 1621 block.nTime = 1231006505;
genesis 1622 block.nBits = 0x1d00ffff;
genesis 1623 block.nNonce = 2083236893;
genesis 1624
genesis 1625 if (fTestNet)
genesis 1626 {
genesis 1627 block.nTime = 1296688602;
genesis 1628 block.nBits = 0x1d07fff8;
genesis 1629 block.nNonce = 384568319;
genesis 1630 }
genesis 1631
genesis 1632
genesis 1633 printf("%s\n", block.GetHash().ToString().c_str());
genesis 1634 printf("%s\n", hashGenesisBlock.ToString().c_str());
genesis 1635 printf("%s\n", block.hashMerkleRoot.ToString().c_str());
genesis 1636 assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
genesis 1637 block.print();
genesis 1638 assert(block.GetHash() == hashGenesisBlock);
genesis 1639
genesis 1640
genesis 1641 unsigned int nFile;
genesis 1642 unsigned int nBlockPos;
genesis 1643 if (!block.WriteToDisk(nFile, nBlockPos))
genesis 1644 return error("LoadBlockIndex() : writing genesis block to disk failed");
genesis 1645 if (!block.AddToBlockIndex(nFile, nBlockPos))
genesis 1646 return error("LoadBlockIndex() : genesis block not accepted");
genesis 1647 }
genesis 1648
genesis 1649 return true;
genesis 1650 }
genesis 1651
genesis 1652
genesis 1653
genesis 1654 void PrintBlockTree()
genesis 1655 {
genesis 1656
genesis 1657 map<CBlockIndex*, vector<CBlockIndex*> > mapNext;
genesis 1658 for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi)
genesis 1659 {
genesis 1660 CBlockIndex* pindex = (*mi).second;
genesis 1661 mapNext[pindex->pprev].push_back(pindex);
genesis 1662
genesis 1663
genesis 1664
genesis 1665 }
genesis 1666
genesis 1667 vector<pair<int, CBlockIndex*> > vStack;
genesis 1668 vStack.push_back(make_pair(0, pindexGenesisBlock));
genesis 1669
genesis 1670 int nPrevCol = 0;
genesis 1671 while (!vStack.empty())
genesis 1672 {
genesis 1673 int nCol = vStack.back().first;
genesis 1674 CBlockIndex* pindex = vStack.back().second;
genesis 1675 vStack.pop_back();
genesis 1676
genesis 1677
genesis 1678 if (nCol > nPrevCol)
genesis 1679 {
genesis 1680 for (int i = 0; i < nCol-1; i++)
genesis 1681 printf("| ");
genesis 1682 printf("|\\\n");
genesis 1683 }
genesis 1684 else if (nCol < nPrevCol)
genesis 1685 {
genesis 1686 for (int i = 0; i < nCol; i++)
genesis 1687 printf("| ");
genesis 1688 printf("|\n");
genesis 1689 }
genesis 1690 nPrevCol = nCol;
genesis 1691
genesis 1692
genesis 1693 for (int i = 0; i < nCol; i++)
genesis 1694 printf("| ");
genesis 1695
genesis 1696
genesis 1697 CBlock block;
genesis 1698 block.ReadFromDisk(pindex);
genesis 1699 printf("%d (%u,%u) %s %s tx %d",
genesis 1700 pindex->nHeight,
genesis 1701 pindex->nFile,
genesis 1702 pindex->nBlockPos,
genesis 1703 block.GetHash().ToString().substr(0,20).c_str(),
genesis 1704 DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
genesis 1705 block.vtx.size());
genesis 1706
genesis 1707 PrintWallets(block);
genesis 1708
genesis 1709
genesis 1710 vector<CBlockIndex*>& vNext = mapNext[pindex];
genesis 1711 for (int i = 0; i < vNext.size(); i++)
genesis 1712 {
genesis 1713 if (vNext[i]->pnext)
genesis 1714 {
genesis 1715 swap(vNext[0], vNext[i]);
genesis 1716 break;
genesis 1717 }
genesis 1718 }
genesis 1719
genesis 1720
genesis 1721 for (int i = 0; i < vNext.size(); i++)
genesis 1722 vStack.push_back(make_pair(nCol+i, vNext[i]));
genesis 1723 }
genesis 1724 }
genesis 1725
genesis 1726
genesis 1727
genesis 1728
genesis 1729
genesis 1730
genesis 1731
genesis 1732
genesis 1733
genesis 1734
genesis 1735
genesis 1736
genesis 1737
genesis 1738
genesis 1739
genesis 1740 map<uint256, CAlert> mapAlerts;
genesis 1741 CCriticalSection cs_mapAlerts;
genesis 1742
genesis 1743 string GetWarnings(string strFor)
genesis 1744 {
genesis 1745 int nPriority = 0;
genesis 1746 string strStatusBar;
genesis 1747 string strRPC;
genesis 1748 if (GetBoolArg("-testsafemode"))
genesis 1749 strRPC = "test";
genesis 1750
genesis 1751
genesis 1752 if (strMiscWarning != "")
genesis 1753 {
genesis 1754 nPriority = 1000;
genesis 1755 strStatusBar = strMiscWarning;
genesis 1756 }
genesis 1757
genesis 1758
genesis 1759 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
genesis 1760 {
genesis 1761 nPriority = 2000;
genesis 1762 strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.";
genesis 1763 }
genesis 1764
genesis 1765
genesis 1766 CRITICAL_BLOCK(cs_mapAlerts)
genesis 1767 {
genesis 1768 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis 1769 {
genesis 1770 const CAlert& alert = item.second;
genesis 1771 if (alert.AppliesToMe() && alert.nPriority > nPriority)
genesis 1772 {
genesis 1773 nPriority = alert.nPriority;
genesis 1774 strStatusBar = alert.strStatusBar;
genesis 1775 }
genesis 1776 }
genesis 1777 }
genesis 1778
genesis 1779 if (strFor == "statusbar")
genesis 1780 return strStatusBar;
genesis 1781 else if (strFor == "rpc")
genesis 1782 return strRPC;
genesis 1783 assert(!"GetWarnings() : invalid parameter");
genesis 1784 return "error";
genesis 1785 }
genesis 1786
genesis 1787 bool CAlert::ProcessAlert()
genesis 1788 {
genesis 1789 if (!CheckSignature())
genesis 1790 return false;
genesis 1791 if (!IsInEffect())
genesis 1792 return false;
genesis 1793
genesis 1794 CRITICAL_BLOCK(cs_mapAlerts)
genesis 1795 {
genesis 1796
genesis 1797 for (map<uint256, CAlert>::iterator mi = mapAlerts.begin(); mi != mapAlerts.end();)
genesis 1798 {
genesis 1799 const CAlert& alert = (*mi).second;
genesis 1800 if (Cancels(alert))
genesis 1801 {
genesis 1802 printf("cancelling alert %d\n", alert.nID);
genesis 1803 mapAlerts.erase(mi++);
genesis 1804 }
genesis 1805 else if (!alert.IsInEffect())
genesis 1806 {
genesis 1807 printf("expiring alert %d\n", alert.nID);
genesis 1808 mapAlerts.erase(mi++);
genesis 1809 }
genesis 1810 else
genesis 1811 mi++;
genesis 1812 }
genesis 1813
genesis 1814
genesis 1815 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis 1816 {
genesis 1817 const CAlert& alert = item.second;
genesis 1818 if (alert.Cancels(*this))
genesis 1819 {
genesis 1820 printf("alert already cancelled by %d\n", alert.nID);
genesis 1821 return false;
genesis 1822 }
genesis 1823 }
genesis 1824
genesis 1825
genesis 1826 mapAlerts.insert(make_pair(GetHash(), *this));
genesis 1827 }
genesis 1828
genesis 1829 printf("accepted alert %d, AppliesToMe()=%d\n", nID, AppliesToMe());
genesis 1830 MainFrameRepaint();
genesis 1831 return true;
genesis 1832 }
genesis 1833
genesis 1834
genesis 1835
genesis 1836
genesis 1837
genesis 1838
genesis 1839
genesis 1840
genesis 1841
genesis 1842
genesis 1843
genesis 1844
genesis 1845
genesis 1846
genesis 1847 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
genesis 1848 {
genesis 1849 switch (inv.type)
genesis 1850 {
genesis 1851 case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
genesis 1852 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
genesis 1853 }
genesis 1854
genesis 1855 return true;
genesis 1856 }
genesis 1857
genesis 1858
genesis 1859
genesis 1860
genesis 1861
genesis 1862
genesis 1863
genesis 1864 unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
genesis 1865
genesis 1866
genesis 1867 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
genesis 1868 {
genesis 1869 static map<unsigned int, vector<unsigned char> > mapReuseKey;
genesis 1870 RandAddSeedPerfmon();
genesis 1871 if (fDebug) {
genesis 1872 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis 1873 printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
genesis 1874 }
genesis 1875 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis 1876 {
genesis 1877 printf("dropmessagestest DROPPING RECV MESSAGE\n");
genesis 1878 return true;
genesis 1879 }
genesis 1880
genesis 1881
genesis 1882
genesis 1883
genesis 1884
genesis 1885 if (strCommand == "version")
genesis 1886 {
genesis 1887
genesis 1888 if (pfrom->nVersion != 0)
genesis 1889 {
genesis 1890 pfrom->Misbehaving(1);
genesis 1891 return false;
genesis 1892 }
genesis 1893
genesis 1894 int64 nTime;
genesis 1895 CAddress addrMe;
genesis 1896 CAddress addrFrom;
genesis 1897 uint64 nNonce = 1;
genesis 1898 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
genesis 1899 if (pfrom->nVersion == 10300)
genesis 1900 pfrom->nVersion = 300;
genesis 1901 if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis 1902 vRecv >> addrFrom >> nNonce;
genesis 1903 if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis 1904 vRecv >> pfrom->strSubVer;
genesis 1905 if (pfrom->nVersion >= 209 && !vRecv.empty())
genesis 1906 vRecv >> pfrom->nStartingHeight;
genesis 1907
genesis 1908 if (pfrom->nVersion == 0)
genesis 1909 return false;
genesis 1910
genesis 1911
genesis 1912 if (nNonce == nLocalHostNonce && nNonce > 1)
genesis 1913 {
genesis 1914 printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
genesis 1915 pfrom->fDisconnect = true;
genesis 1916 return true;
genesis 1917 }
genesis 1918
genesis 1919
genesis 1920 if (pfrom->fInbound)
genesis 1921 pfrom->PushVersion();
genesis 1922
genesis 1923 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
genesis 1924
genesis 1925 AddTimeData(pfrom->addr.ip, nTime);
genesis 1926
genesis 1927
genesis 1928 if (pfrom->nVersion >= 209)
genesis 1929 pfrom->PushMessage("verack");
genesis 1930 pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1931 if (pfrom->nVersion < 209)
genesis 1932 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1933
genesis 1934 if (!pfrom->fInbound)
genesis 1935 {
genesis 1936
genesis 1937 if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis 1938 {
genesis 1939 CAddress addr(addrLocalHost);
genesis 1940 addr.nTime = GetAdjustedTime();
genesis 1941 pfrom->PushAddress(addr);
genesis 1942 }
genesis 1943
genesis 1944
genesis 1945 if (pfrom->nVersion >= 31402 || mapAddresses.size() < 1000)
genesis 1946 {
genesis 1947 pfrom->PushMessage("getaddr");
genesis 1948 pfrom->fGetAddr = true;
genesis 1949 }
genesis 1950 }
genesis 1951
genesis 1952
genesis 1953 static int nAskedForBlocks;
genesis 1954 if (!pfrom->fClient &&
genesis 1955 (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
genesis 1956 (nAskedForBlocks < 1 || vNodes.size() <= 1))
genesis 1957 {
genesis 1958 nAskedForBlocks++;
genesis 1959 pfrom->PushGetBlocks(pindexBest, uint256(0));
genesis 1960 }
genesis 1961
genesis 1962
genesis 1963 CRITICAL_BLOCK(cs_mapAlerts)
genesis 1964 BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts)
genesis 1965 item.second.RelayTo(pfrom);
genesis 1966
genesis 1967 pfrom->fSuccessfullyConnected = true;
genesis 1968
genesis 1969 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
genesis 1970
genesis 1971 cPeerBlockCounts.input(pfrom->nStartingHeight);
genesis 1972 }
genesis 1973
genesis 1974
genesis 1975 else if (pfrom->nVersion == 0)
genesis 1976 {
genesis 1977
genesis 1978 pfrom->Misbehaving(1);
genesis 1979 return false;
genesis 1980 }
genesis 1981
genesis 1982
genesis 1983 else if (strCommand == "verack")
genesis 1984 {
genesis 1985 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1986 }
genesis 1987
genesis 1988
genesis 1989 else if (strCommand == "addr")
genesis 1990 {
genesis 1991 vector<CAddress> vAddr;
genesis 1992 vRecv >> vAddr;
genesis 1993
genesis 1994
genesis 1995 if (pfrom->nVersion < 209)
genesis 1996 return true;
genesis 1997 if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000)
genesis 1998 return true;
genesis 1999 if (vAddr.size() > 1000)
genesis 2000 {
genesis 2001 pfrom->Misbehaving(20);
genesis 2002 return error("message addr size() = %d", vAddr.size());
genesis 2003 }
genesis 2004
genesis 2005
genesis 2006 CAddrDB addrDB;
genesis 2007 addrDB.TxnBegin();
genesis 2008 int64 nNow = GetAdjustedTime();
genesis 2009 int64 nSince = nNow - 10 * 60;
genesis 2010 BOOST_FOREACH(CAddress& addr, vAddr)
genesis 2011 {
genesis 2012 if (fShutdown)
genesis 2013 return true;
genesis 2014
genesis 2015 if (!addr.IsIPv4())
genesis 2016 continue;
genesis 2017 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
genesis 2018 addr.nTime = nNow - 5 * 24 * 60 * 60;
genesis 2019 AddAddress(addr, 2 * 60 * 60, &addrDB);
genesis 2020 pfrom->AddAddressKnown(addr);
genesis 2021 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
genesis 2022 {
genesis 2023
genesis 2024 CRITICAL_BLOCK(cs_vNodes)
genesis 2025 {
genesis 2026
genesis 2027
genesis 2028 static uint256 hashSalt;
genesis 2029 if (hashSalt == 0)
genesis 2030 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis 2031 uint256 hashRand = hashSalt ^ (((int64)addr.ip)<<32) ^ ((GetTime()+addr.ip)/(24*60*60));
genesis 2032 hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis 2033 multimap<uint256, CNode*> mapMix;
genesis 2034 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 2035 {
genesis 2036 if (pnode->nVersion < 31402)
genesis 2037 continue;
genesis 2038 unsigned int nPointer;
genesis 2039 memcpy(&nPointer, &pnode, sizeof(nPointer));
genesis 2040 uint256 hashKey = hashRand ^ nPointer;
genesis 2041 hashKey = Hash(BEGIN(hashKey), END(hashKey));
genesis 2042 mapMix.insert(make_pair(hashKey, pnode));
genesis 2043 }
genesis 2044 int nRelayNodes = 2;
genesis 2045 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
genesis 2046 ((*mi).second)->PushAddress(addr);
genesis 2047 }
genesis 2048 }
genesis 2049 }
genesis 2050 addrDB.TxnCommit();
genesis 2051 if (vAddr.size() < 1000)
genesis 2052 pfrom->fGetAddr = false;
genesis 2053 }
genesis 2054
genesis 2055
genesis 2056 else if (strCommand == "inv")
genesis 2057 {
genesis 2058 vector<CInv> vInv;
genesis 2059 vRecv >> vInv;
genesis 2060 if (vInv.size() > 50000)
genesis 2061 {
genesis 2062 pfrom->Misbehaving(20);
genesis 2063 return error("message inv size() = %d", vInv.size());
genesis 2064 }
genesis 2065
genesis 2066 CTxDB txdb("r");
genesis 2067 BOOST_FOREACH(const CInv& inv, vInv)
genesis 2068 {
genesis 2069 if (fShutdown)
genesis 2070 return true;
genesis 2071 pfrom->AddInventoryKnown(inv);
genesis 2072
genesis 2073 bool fAlreadyHave = AlreadyHave(txdb, inv);
genesis 2074 if (fDebug)
genesis 2075 printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
genesis 2076
genesis 2077 if (!fAlreadyHave)
genesis 2078 pfrom->AskFor(inv);
genesis 2079 else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
genesis 2080 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
genesis 2081
genesis 2082
genesis 2083 Inventory(inv.hash);
genesis 2084 }
genesis 2085 }
genesis 2086
genesis 2087
genesis 2088 else if (strCommand == "getdata")
genesis 2089 {
genesis 2090 vector<CInv> vInv;
genesis 2091 vRecv >> vInv;
genesis 2092 if (vInv.size() > 50000)
genesis 2093 {
genesis 2094 pfrom->Misbehaving(20);
genesis 2095 return error("message getdata size() = %d", vInv.size());
genesis 2096 }
genesis 2097
genesis 2098 BOOST_FOREACH(const CInv& inv, vInv)
genesis 2099 {
genesis 2100 if (fShutdown)
genesis 2101 return true;
genesis 2102 printf("received getdata for: %s\n", inv.ToString().c_str());
genesis 2103
genesis 2104 if (inv.type == MSG_BLOCK)
genesis 2105 {
genesis 2106
genesis 2107 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
genesis 2108 if (mi != mapBlockIndex.end())
genesis 2109 {
genesis 2110 CBlock block;
genesis 2111 block.ReadFromDisk((*mi).second);
genesis 2112 pfrom->PushMessage("block", block);
genesis 2113
genesis 2114
genesis 2115 if (inv.hash == pfrom->hashContinue)
genesis 2116 {
genesis 2117
genesis 2118
genesis 2119
genesis 2120 vector<CInv> vInv;
genesis 2121 vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
genesis 2122 pfrom->PushMessage("inv", vInv);
genesis 2123 pfrom->hashContinue = 0;
genesis 2124 }
genesis 2125 }
genesis 2126 }
genesis 2127 else if (inv.IsKnownType())
genesis 2128 {
genesis 2129
genesis 2130 CRITICAL_BLOCK(cs_mapRelay)
genesis 2131 {
genesis 2132 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
genesis 2133 if (mi != mapRelay.end())
genesis 2134 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
genesis 2135 }
genesis 2136 }
genesis 2137
genesis 2138
genesis 2139 Inventory(inv.hash);
genesis 2140 }
genesis 2141 }
genesis 2142
genesis 2143
genesis 2144 else if (strCommand == "getblocks")
genesis 2145 {
genesis 2146 CBlockLocator locator;
genesis 2147 uint256 hashStop;
genesis 2148 vRecv >> locator >> hashStop;
genesis 2149
genesis 2150
genesis 2151 CBlockIndex* pindex = locator.GetBlockIndex();
genesis 2152
genesis 2153
genesis 2154 if (pindex)
genesis 2155 pindex = pindex->pnext;
genesis 2156 int nLimit = 500 + locator.GetDistanceBack();
genesis 2157 unsigned int nBytes = 0;
genesis 2158 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis 2159 for (; pindex; pindex = pindex->pnext)
genesis 2160 {
genesis 2161 if (pindex->GetBlockHash() == hashStop)
genesis 2162 {
genesis 2163 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis 2164 break;
genesis 2165 }
genesis 2166 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
genesis 2167 CBlock block;
genesis 2168 block.ReadFromDisk(pindex, true);
genesis 2169 nBytes += block.GetSerializeSize(SER_NETWORK);
genesis 2170 if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
genesis 2171 {
genesis 2172
genesis 2173
genesis 2174 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis 2175 pfrom->hashContinue = pindex->GetBlockHash();
genesis 2176 break;
genesis 2177 }
genesis 2178 }
genesis 2179 }
genesis 2180
genesis 2181
genesis 2182 else if (strCommand == "getheaders")
genesis 2183 {
genesis 2184 CBlockLocator locator;
genesis 2185 uint256 hashStop;
genesis 2186 vRecv >> locator >> hashStop;
genesis 2187
genesis 2188 CBlockIndex* pindex = NULL;
genesis 2189 if (locator.IsNull())
genesis 2190 {
genesis 2191
genesis 2192 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
genesis 2193 if (mi == mapBlockIndex.end())
genesis 2194 return true;
genesis 2195 pindex = (*mi).second;
genesis 2196 }
genesis 2197 else
genesis 2198 {
genesis 2199
genesis 2200 pindex = locator.GetBlockIndex();
genesis 2201 if (pindex)
genesis 2202 pindex = pindex->pnext;
genesis 2203 }
genesis 2204
genesis 2205 vector<CBlock> vHeaders;
genesis 2206 int nLimit = 2000 + locator.GetDistanceBack();
genesis 2207 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis 2208 for (; pindex; pindex = pindex->pnext)
genesis 2209 {
genesis 2210 vHeaders.push_back(pindex->GetBlockHeader());
genesis 2211 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
genesis 2212 break;
genesis 2213 }
genesis 2214 pfrom->PushMessage("headers", vHeaders);
genesis 2215 }
genesis 2216
genesis 2217
genesis 2218 else if (strCommand == "tx")
genesis 2219 {
genesis 2220 vector<uint256> vWorkQueue;
genesis 2221 CDataStream vMsg(vRecv);
genesis 2222 CTransaction tx;
genesis 2223 vRecv >> tx;
genesis 2224
genesis 2225 CInv inv(MSG_TX, tx.GetHash());
genesis 2226 pfrom->AddInventoryKnown(inv);
genesis 2227
genesis 2228 bool fMissingInputs = false;
genesis 2229 if (tx.AcceptToMemoryPool(true, &fMissingInputs))
genesis 2230 {
genesis 2231 SyncWithWallets(tx, NULL, true);
genesis 2232 RelayMessage(inv, vMsg);
genesis 2233 mapAlreadyAskedFor.erase(inv);
genesis 2234 vWorkQueue.push_back(inv.hash);
genesis 2235
genesis 2236
genesis 2237 for (int i = 0; i < vWorkQueue.size(); i++)
genesis 2238 {
genesis 2239 uint256 hashPrev = vWorkQueue[i];
genesis 2240 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
genesis 2241 mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
genesis 2242 ++mi)
genesis 2243 {
genesis 2244 const CDataStream& vMsg = *((*mi).second);
genesis 2245 CTransaction tx;
genesis 2246 CDataStream(vMsg) >> tx;
genesis 2247 CInv inv(MSG_TX, tx.GetHash());
genesis 2248
genesis 2249 if (tx.AcceptToMemoryPool(true))
genesis 2250 {
genesis 2251 printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis 2252 SyncWithWallets(tx, NULL, true);
genesis 2253 RelayMessage(inv, vMsg);
genesis 2254 mapAlreadyAskedFor.erase(inv);
genesis 2255 vWorkQueue.push_back(inv.hash);
genesis 2256 }
genesis 2257 }
genesis 2258 }
genesis 2259
genesis 2260 BOOST_FOREACH(uint256 hash, vWorkQueue)
genesis 2261 EraseOrphanTx(hash);
genesis 2262 }
genesis 2263 else if (fMissingInputs)
genesis 2264 {
genesis 2265 printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis 2266 AddOrphanTx(vMsg);
genesis 2267
genesis 2268
genesis 2269 int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
genesis 2270 if (nEvicted > 0)
genesis 2271 printf("mapOrphan overflow, removed %d tx\n", nEvicted);
genesis 2272 }
genesis 2273 if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
genesis 2274 }
genesis 2275
genesis 2276
genesis 2277 else if (strCommand == "block")
genesis 2278 {
genesis 2279 CBlock block;
genesis 2280 vRecv >> block;
genesis 2281
genesis 2282 printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
genesis 2283
genesis 2284
genesis 2285 CInv inv(MSG_BLOCK, block.GetHash());
genesis 2286 pfrom->AddInventoryKnown(inv);
genesis 2287
genesis 2288 if (ProcessBlock(pfrom, &block))
genesis 2289 mapAlreadyAskedFor.erase(inv);
genesis 2290 if (block.nDoS) pfrom->Misbehaving(block.nDoS);
genesis 2291 }
genesis 2292
genesis 2293
genesis 2294 else if (strCommand == "getaddr")
genesis 2295 {
genesis 2296
genesis 2297 pfrom->vAddrToSend.clear();
genesis 2298 int64 nSince = GetAdjustedTime() - 3 * 60 * 60;
genesis 2299 CRITICAL_BLOCK(cs_mapAddresses)
genesis 2300 {
genesis 2301 unsigned int nCount = 0;
genesis 2302 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis 2303 {
genesis 2304 const CAddress& addr = item.second;
genesis 2305 if (addr.nTime > nSince)
genesis 2306 nCount++;
genesis 2307 }
genesis 2308 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis 2309 {
genesis 2310 const CAddress& addr = item.second;
genesis 2311 if (addr.nTime > nSince && GetRand(nCount) < 2500)
genesis 2312 pfrom->PushAddress(addr);
genesis 2313 }
genesis 2314 }
genesis 2315 }
genesis 2316
genesis 2317
genesis 2318 else if (strCommand == "checkorder")
genesis 2319 {
genesis 2320 uint256 hashReply;
genesis 2321 vRecv >> hashReply;
genesis 2322
genesis 2323 if (!GetBoolArg("-allowreceivebyip"))
genesis 2324 {
genesis 2325 pfrom->PushMessage("reply", hashReply, (int)2, string(""));
genesis 2326 return true;
genesis 2327 }
genesis 2328
genesis 2329 CWalletTx order;
genesis 2330 vRecv >> order;
genesis 2331
genesis 2332
genesis 2333
genesis 2334
genesis 2335 if (!mapReuseKey.count(pfrom->addr.ip))
genesis 2336 pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
genesis 2337
genesis 2338
genesis 2339 CScript scriptPubKey;
genesis 2340 scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
genesis 2341 pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
genesis 2342 }
genesis 2343
genesis 2344
genesis 2345 else if (strCommand == "reply")
genesis 2346 {
genesis 2347 uint256 hashReply;
genesis 2348 vRecv >> hashReply;
genesis 2349
genesis 2350 CRequestTracker tracker;
genesis 2351 CRITICAL_BLOCK(pfrom->cs_mapRequests)
genesis 2352 {
genesis 2353 map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
genesis 2354 if (mi != pfrom->mapRequests.end())
genesis 2355 {
genesis 2356 tracker = (*mi).second;
genesis 2357 pfrom->mapRequests.erase(mi);
genesis 2358 }
genesis 2359 }
genesis 2360 if (!tracker.IsNull())
genesis 2361 tracker.fn(tracker.param1, vRecv);
genesis 2362 }
genesis 2363
genesis 2364
genesis 2365 else if (strCommand == "ping")
genesis 2366 {
genesis 2367 }
genesis 2368
genesis 2369
genesis 2370 else if (strCommand == "alert")
genesis 2371 {
genesis 2372 CAlert alert;
genesis 2373 vRecv >> alert;
genesis 2374
genesis 2375 if (alert.ProcessAlert())
genesis 2376 {
genesis 2377
genesis 2378 pfrom->setKnown.insert(alert.GetHash());
genesis 2379 CRITICAL_BLOCK(cs_vNodes)
genesis 2380 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 2381 alert.RelayTo(pnode);
genesis 2382 }
genesis 2383 }
genesis 2384
genesis 2385
genesis 2386 else
genesis 2387 {
genesis 2388
genesis 2389 }
genesis 2390
genesis 2391
genesis 2392
genesis 2393 if (pfrom->fNetworkNode)
genesis 2394 if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
genesis 2395 AddressCurrentlyConnected(pfrom->addr);
genesis 2396
genesis 2397
genesis 2398 return true;
genesis 2399 }
genesis 2400
genesis 2401 bool ProcessMessages(CNode* pfrom)
genesis 2402 {
genesis 2403 CDataStream& vRecv = pfrom->vRecv;
genesis 2404 if (vRecv.empty())
genesis 2405 return true;
genesis 2406
genesis 2407
genesis 2408
genesis 2409
genesis 2410
genesis 2411
genesis 2412
genesis 2413
genesis 2414
genesis 2415
genesis 2416
genesis 2417
genesis 2418 loop
genesis 2419 {
genesis 2420
genesis 2421 CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
genesis 2422 int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
genesis 2423 if (vRecv.end() - pstart < nHeaderSize)
genesis 2424 {
genesis 2425 if (vRecv.size() > nHeaderSize)
genesis 2426 {
genesis 2427 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
genesis 2428 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
genesis 2429 }
genesis 2430 break;
genesis 2431 }
genesis 2432 if (pstart - vRecv.begin() > 0)
genesis 2433 printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
genesis 2434 vRecv.erase(vRecv.begin(), pstart);
genesis 2435
genesis 2436
genesis 2437 vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
genesis 2438 CMessageHeader hdr;
genesis 2439 vRecv >> hdr;
genesis 2440 if (!hdr.IsValid())
genesis 2441 {
genesis 2442 printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
genesis 2443 continue;
genesis 2444 }
genesis 2445 string strCommand = hdr.GetCommand();
genesis 2446
genesis 2447
genesis 2448 unsigned int nMessageSize = hdr.nMessageSize;
genesis 2449 if (nMessageSize > MAX_SIZE)
genesis 2450 {
genesis 2451 printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
genesis 2452 continue;
genesis 2453 }
genesis 2454 if (nMessageSize > vRecv.size())
genesis 2455 {
genesis 2456
genesis 2457 vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
genesis 2458 break;
genesis 2459 }
genesis 2460
genesis 2461
genesis 2462 if (vRecv.GetVersion() >= 209)
genesis 2463 {
genesis 2464 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
genesis 2465 unsigned int nChecksum = 0;
genesis 2466 memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis 2467 if (nChecksum != hdr.nChecksum)
genesis 2468 {
genesis 2469 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
genesis 2470 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
genesis 2471 continue;
genesis 2472 }
genesis 2473 }
genesis 2474
genesis 2475
genesis 2476 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
genesis 2477 vRecv.ignore(nMessageSize);
genesis 2478
genesis 2479
genesis 2480 bool fRet = false;
genesis 2481 try
genesis 2482 {
genesis 2483 CRITICAL_BLOCK(cs_main)
genesis 2484 fRet = ProcessMessage(pfrom, strCommand, vMsg);
genesis 2485 if (fShutdown)
genesis 2486 return true;
genesis 2487 }
genesis 2488 catch (std::ios_base::failure& e)
genesis 2489 {
genesis 2490 if (strstr(e.what(), "end of data"))
genesis 2491 {
genesis 2492
genesis 2493 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());
genesis 2494 }
genesis 2495 else if (strstr(e.what(), "size too large"))
genesis 2496 {
genesis 2497
genesis 2498 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
genesis 2499 }
genesis 2500 else
genesis 2501 {
genesis 2502 PrintExceptionContinue(&e, "ProcessMessage()");
genesis 2503 }
genesis 2504 }
genesis 2505 catch (std::exception& e) {
genesis 2506 PrintExceptionContinue(&e, "ProcessMessage()");
genesis 2507 } catch (...) {
genesis 2508 PrintExceptionContinue(NULL, "ProcessMessage()");
genesis 2509 }
genesis 2510
genesis 2511 if (!fRet)
genesis 2512 printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
genesis 2513 }
genesis 2514
genesis 2515 vRecv.Compact();
genesis 2516 return true;
genesis 2517 }
genesis 2518
genesis 2519
genesis 2520 bool SendMessages(CNode* pto, bool fSendTrickle)
genesis 2521 {
genesis 2522 CRITICAL_BLOCK(cs_main)
genesis 2523 {
genesis 2524
genesis 2525 if (pto->nVersion == 0)
genesis 2526 return true;
genesis 2527
genesis 2528
genesis 2529 if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
genesis 2530 pto->PushMessage("ping");
genesis 2531
genesis 2532
genesis 2533 ResendWalletTransactions();
genesis 2534
genesis 2535
genesis 2536 static int64 nLastRebroadcast;
genesis 2537 if (GetTime() - nLastRebroadcast > 24 * 60 * 60)
genesis 2538 {
genesis 2539 nLastRebroadcast = GetTime();
genesis 2540 CRITICAL_BLOCK(cs_vNodes)
genesis 2541 {
genesis 2542 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 2543 {
genesis 2544
genesis 2545 pnode->setAddrKnown.clear();
genesis 2546
genesis 2547
genesis 2548 if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis 2549 {
genesis 2550 CAddress addr(addrLocalHost);
genesis 2551 addr.nTime = GetAdjustedTime();
genesis 2552 pnode->PushAddress(addr);
genesis 2553 }
genesis 2554 }
genesis 2555 }
genesis 2556 }
genesis 2557
genesis 2558
genesis 2559 static int64 nLastClear;
genesis 2560 if (nLastClear == 0)
genesis 2561 nLastClear = GetTime();
genesis 2562 if (GetTime() - nLastClear > 10 * 60 && vNodes.size() >= 3)
genesis 2563 {
genesis 2564 nLastClear = GetTime();
genesis 2565 CRITICAL_BLOCK(cs_mapAddresses)
genesis 2566 {
genesis 2567 CAddrDB addrdb;
genesis 2568 int64 nSince = GetAdjustedTime() - 14 * 24 * 60 * 60;
genesis 2569 for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.begin();
genesis 2570 mi != mapAddresses.end();)
genesis 2571 {
genesis 2572 const CAddress& addr = (*mi).second;
genesis 2573 if (addr.nTime < nSince)
genesis 2574 {
genesis 2575 if (mapAddresses.size() < 1000 || GetTime() > nLastClear + 20)
genesis 2576 break;
genesis 2577 addrdb.EraseAddress(addr);
genesis 2578 mapAddresses.erase(mi++);
genesis 2579 }
genesis 2580 else
genesis 2581 mi++;
genesis 2582 }
genesis 2583 }
genesis 2584 }
genesis 2585
genesis 2586
genesis 2587
genesis 2588
genesis 2589
genesis 2590 if (fSendTrickle)
genesis 2591 {
genesis 2592 vector<CAddress> vAddr;
genesis 2593 vAddr.reserve(pto->vAddrToSend.size());
genesis 2594 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
genesis 2595 {
genesis 2596
genesis 2597 if (pto->setAddrKnown.insert(addr).second)
genesis 2598 {
genesis 2599 vAddr.push_back(addr);
genesis 2600
genesis 2601 if (vAddr.size() >= 1000)
genesis 2602 {
genesis 2603 pto->PushMessage("addr", vAddr);
genesis 2604 vAddr.clear();
genesis 2605 }
genesis 2606 }
genesis 2607 }
genesis 2608 pto->vAddrToSend.clear();
genesis 2609 if (!vAddr.empty())
genesis 2610 pto->PushMessage("addr", vAddr);
genesis 2611 }
genesis 2612
genesis 2613
genesis 2614
genesis 2615
genesis 2616
genesis 2617 vector<CInv> vInv;
genesis 2618 vector<CInv> vInvWait;
genesis 2619 CRITICAL_BLOCK(pto->cs_inventory)
genesis 2620 {
genesis 2621 vInv.reserve(pto->vInventoryToSend.size());
genesis 2622 vInvWait.reserve(pto->vInventoryToSend.size());
genesis 2623 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
genesis 2624 {
genesis 2625 if (pto->setInventoryKnown.count(inv))
genesis 2626 continue;
genesis 2627
genesis 2628
genesis 2629 if (inv.type == MSG_TX && !fSendTrickle)
genesis 2630 {
genesis 2631
genesis 2632 static uint256 hashSalt;
genesis 2633 if (hashSalt == 0)
genesis 2634 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis 2635 uint256 hashRand = inv.hash ^ hashSalt;
genesis 2636 hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis 2637 bool fTrickleWait = ((hashRand & 3) != 0);
genesis 2638
genesis 2639
genesis 2640 if (!fTrickleWait)
genesis 2641 {
genesis 2642 CWalletTx wtx;
genesis 2643 if (GetTransaction(inv.hash, wtx))
genesis 2644 if (wtx.fFromMe)
genesis 2645 fTrickleWait = true;
genesis 2646 }
genesis 2647
genesis 2648 if (fTrickleWait)
genesis 2649 {
genesis 2650 vInvWait.push_back(inv);
genesis 2651 continue;
genesis 2652 }
genesis 2653 }
genesis 2654
genesis 2655
genesis 2656 if (pto->setInventoryKnown.insert(inv).second)
genesis 2657 {
genesis 2658 vInv.push_back(inv);
genesis 2659 if (vInv.size() >= 1000)
genesis 2660 {
genesis 2661 pto->PushMessage("inv", vInv);
genesis 2662 vInv.clear();
genesis 2663 }
genesis 2664 }
genesis 2665 }
genesis 2666 pto->vInventoryToSend = vInvWait;
genesis 2667 }
genesis 2668 if (!vInv.empty())
genesis 2669 pto->PushMessage("inv", vInv);
genesis 2670
genesis 2671
genesis 2672
genesis 2673
genesis 2674
genesis 2675 vector<CInv> vGetData;
genesis 2676 int64 nNow = GetTime() * 1000000;
genesis 2677 CTxDB txdb("r");
genesis 2678 while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
genesis 2679 {
genesis 2680 const CInv& inv = (*pto->mapAskFor.begin()).second;
genesis 2681 if (!AlreadyHave(txdb, inv))
genesis 2682 {
genesis 2683 printf("sending getdata: %s\n", inv.ToString().c_str());
genesis 2684 vGetData.push_back(inv);
genesis 2685 if (vGetData.size() >= 1000)
genesis 2686 {
genesis 2687 pto->PushMessage("getdata", vGetData);
genesis 2688 vGetData.clear();
genesis 2689 }
genesis 2690 }
genesis 2691 mapAlreadyAskedFor[inv] = nNow;
genesis 2692 pto->mapAskFor.erase(pto->mapAskFor.begin());
genesis 2693 }
genesis 2694 if (!vGetData.empty())
genesis 2695 pto->PushMessage("getdata", vGetData);
genesis 2696
genesis 2697 }
genesis 2698 return true;
genesis 2699 }
genesis 2700
genesis 2701
genesis 2702
genesis 2703
genesis 2704
genesis 2705
genesis 2706
genesis 2707
genesis 2708
genesis 2709
genesis 2710
genesis 2711
genesis 2712
genesis 2713
genesis 2714
genesis 2715
genesis 2716
genesis 2717
genesis 2718
genesis 2719 int static FormatHashBlocks(void* pbuffer, unsigned int len)
genesis 2720 {
genesis 2721 unsigned char* pdata = (unsigned char*)pbuffer;
genesis 2722 unsigned int blocks = 1 + ((len + 8) / 64);
genesis 2723 unsigned char* pend = pdata + 64 * blocks;
genesis 2724 memset(pdata + len, 0, 64 * blocks - len);
genesis 2725 pdata[len] = 0x80;
genesis 2726 unsigned int bits = len * 8;
genesis 2727 pend[-1] = (bits >> 0) & 0xff;
genesis 2728 pend[-2] = (bits >> 8) & 0xff;
genesis 2729 pend[-3] = (bits >> 16) & 0xff;
genesis 2730 pend[-4] = (bits >> 24) & 0xff;
genesis 2731 return blocks;
genesis 2732 }
genesis 2733
genesis 2734 static const unsigned int pSHA256InitState[8] =
genesis 2735 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
genesis 2736
genesis 2737 void SHA256Transform(void* pstate, void* pinput, const void* pinit)
genesis 2738 {
genesis 2739 SHA256_CTX ctx;
genesis 2740 unsigned char data[64];
genesis 2741
genesis 2742 SHA256_Init(&ctx);
genesis 2743
genesis 2744 for (int i = 0; i < 16; i++)
genesis 2745 ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]);
genesis 2746
genesis 2747 for (int i = 0; i < 8; i++)
genesis 2748 ctx.h[i] = ((uint32_t*)pinit)[i];
genesis 2749
genesis 2750 SHA256_Update(&ctx, data, sizeof(data));
genesis 2751 for (int i = 0; i < 8; i++)
genesis 2752 ((uint32_t*)pstate)[i] = ctx.h[i];
genesis 2753 }
genesis 2754
genesis 2755
genesis 2756
genesis 2757
genesis 2758
genesis 2759
genesis 2760
genesis 2761
genesis 2762 unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
genesis 2763 {
genesis 2764 unsigned int& nNonce = *(unsigned int*)(pdata + 12);
genesis 2765 for (;;)
genesis 2766 {
genesis 2767
genesis 2768
genesis 2769
genesis 2770 nNonce++;
genesis 2771 SHA256Transform(phash1, pdata, pmidstate);
genesis 2772 SHA256Transform(phash, phash1, pSHA256InitState);
genesis 2773
genesis 2774
genesis 2775
genesis 2776 if (((unsigned short*)phash)[14] == 0)
genesis 2777 return nNonce;
genesis 2778
genesis 2779
genesis 2780 if ((nNonce & 0xffff) == 0)
genesis 2781 {
genesis 2782 nHashesDone = 0xffff+1;
genesis 2783 return -1;
genesis 2784 }
genesis 2785 }
genesis 2786 }
genesis 2787
genesis 2788
genesis 2789 class COrphan
genesis 2790 {
genesis 2791 public:
genesis 2792 CTransaction* ptx;
genesis 2793 set<uint256> setDependsOn;
genesis 2794 double dPriority;
genesis 2795
genesis 2796 COrphan(CTransaction* ptxIn)
genesis 2797 {
genesis 2798 ptx = ptxIn;
genesis 2799 dPriority = 0;
genesis 2800 }
genesis 2801
genesis 2802 void print() const
genesis 2803 {
genesis 2804 printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority);
genesis 2805 BOOST_FOREACH(uint256 hash, setDependsOn)
genesis 2806 printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
genesis 2807 }
genesis 2808 };
genesis 2809
genesis 2810
genesis 2811 CBlock* CreateNewBlock(CReserveKey& reservekey)
genesis 2812 {
genesis 2813 CBlockIndex* pindexPrev = pindexBest;
genesis 2814
genesis 2815
genesis 2816 auto_ptr<CBlock> pblock(new CBlock());
genesis 2817 if (!pblock.get())
genesis 2818 return NULL;
genesis 2819
genesis 2820
genesis 2821 CTransaction txNew;
genesis 2822 txNew.vin.resize(1);
genesis 2823 txNew.vin[0].prevout.SetNull();
genesis 2824 txNew.vout.resize(1);
genesis 2825 txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
genesis 2826
genesis 2827
genesis 2828 pblock->vtx.push_back(txNew);
genesis 2829
genesis 2830
genesis 2831 int64 nFees = 0;
genesis 2832 CRITICAL_BLOCK(cs_main)
genesis 2833 CRITICAL_BLOCK(cs_mapTransactions)
genesis 2834 {
genesis 2835 CTxDB txdb("r");
genesis 2836
genesis 2837
genesis 2838 list<COrphan> vOrphan;
genesis 2839 map<uint256, vector<COrphan*> > mapDependers;
genesis 2840 multimap<double, CTransaction*> mapPriority;
genesis 2841 for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
genesis 2842 {
genesis 2843 CTransaction& tx = (*mi).second;
genesis 2844 if (tx.IsCoinBase() || !tx.IsFinal())
genesis 2845 continue;
genesis 2846
genesis 2847 COrphan* porphan = NULL;
genesis 2848 double dPriority = 0;
genesis 2849 BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis 2850 {
genesis 2851
genesis 2852 CTransaction txPrev;
genesis 2853 CTxIndex txindex;
genesis 2854 if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
genesis 2855 {
genesis 2856
genesis 2857 if (!porphan)
genesis 2858 {
genesis 2859
genesis 2860 vOrphan.push_back(COrphan(&tx));
genesis 2861 porphan = &vOrphan.back();
genesis 2862 }
genesis 2863 mapDependers[txin.prevout.hash].push_back(porphan);
genesis 2864 porphan->setDependsOn.insert(txin.prevout.hash);
genesis 2865 continue;
genesis 2866 }
genesis 2867 int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
genesis 2868
genesis 2869
genesis 2870 int nConf = txindex.GetDepthInMainChain();
genesis 2871
genesis 2872 dPriority += (double)nValueIn * nConf;
genesis 2873
genesis 2874 if (fDebug && GetBoolArg("-printpriority"))
genesis 2875 printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
genesis 2876 }
genesis 2877
genesis 2878
genesis 2879 dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
genesis 2880
genesis 2881 if (porphan)
genesis 2882 porphan->dPriority = dPriority;
genesis 2883 else
genesis 2884 mapPriority.insert(make_pair(-dPriority, &(*mi).second));
genesis 2885
genesis 2886 if (fDebug && GetBoolArg("-printpriority"))
genesis 2887 {
genesis 2888 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
genesis 2889 if (porphan)
genesis 2890 porphan->print();
genesis 2891 printf("\n");
genesis 2892 }
genesis 2893 }
genesis 2894
genesis 2895
genesis 2896 map<uint256, CTxIndex> mapTestPool;
genesis 2897 uint64 nBlockSize = 1000;
genesis 2898 int nBlockSigOps = 100;
genesis 2899 while (!mapPriority.empty())
genesis 2900 {
genesis 2901
genesis 2902 double dPriority = -(*mapPriority.begin()).first;
genesis 2903 CTransaction& tx = *(*mapPriority.begin()).second;
genesis 2904 mapPriority.erase(mapPriority.begin());
genesis 2905
genesis 2906
genesis 2907 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
genesis 2908 if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
genesis 2909 continue;
genesis 2910 int nTxSigOps = tx.GetSigOpCount();
genesis 2911 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
genesis 2912 continue;
genesis 2913
genesis 2914
genesis 2915 bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
genesis 2916 int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
genesis 2917
genesis 2918
genesis 2919
genesis 2920 map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
genesis 2921 bool fInvalid;
genesis 2922 if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
genesis 2923 continue;
genesis 2924 swap(mapTestPool, mapTestPoolTmp);
genesis 2925
genesis 2926
genesis 2927 pblock->vtx.push_back(tx);
genesis 2928 nBlockSize += nTxSize;
genesis 2929 nBlockSigOps += nTxSigOps;
genesis 2930
genesis 2931
genesis 2932 uint256 hash = tx.GetHash();
genesis 2933 if (mapDependers.count(hash))
genesis 2934 {
genesis 2935 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
genesis 2936 {
genesis 2937 if (!porphan->setDependsOn.empty())
genesis 2938 {
genesis 2939 porphan->setDependsOn.erase(hash);
genesis 2940 if (porphan->setDependsOn.empty())
genesis 2941 mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
genesis 2942 }
genesis 2943 }
genesis 2944 }
genesis 2945 }
genesis 2946 }
genesis 2947 pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
genesis 2948
genesis 2949
genesis 2950 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
genesis 2951 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis 2952 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis 2953 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
genesis 2954 pblock->nNonce = 0;
genesis 2955
genesis 2956 return pblock.release();
genesis 2957 }
genesis 2958
genesis 2959
genesis 2960 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
genesis 2961 {
genesis 2962
genesis 2963 static uint256 hashPrevBlock;
genesis 2964 if (hashPrevBlock != pblock->hashPrevBlock)
genesis 2965 {
genesis 2966 nExtraNonce = 0;
genesis 2967 hashPrevBlock = pblock->hashPrevBlock;
genesis 2968 }
genesis 2969 ++nExtraNonce;
genesis 2970 pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce);
genesis 2971 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis 2972 }
genesis 2973
genesis 2974
genesis 2975 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
genesis 2976 {
genesis 2977
genesis 2978
genesis 2979
genesis 2980 struct
genesis 2981 {
genesis 2982 struct unnamed2
genesis 2983 {
genesis 2984 int nVersion;
genesis 2985 uint256 hashPrevBlock;
genesis 2986 uint256 hashMerkleRoot;
genesis 2987 unsigned int nTime;
genesis 2988 unsigned int nBits;
genesis 2989 unsigned int nNonce;
genesis 2990 }
genesis 2991 block;
genesis 2992 unsigned char pchPadding0[64];
genesis 2993 uint256 hash1;
genesis 2994 unsigned char pchPadding1[64];
genesis 2995 }
genesis 2996 tmp;
genesis 2997 memset(&tmp, 0, sizeof(tmp));
genesis 2998
genesis 2999 tmp.block.nVersion = pblock->nVersion;
genesis 3000 tmp.block.hashPrevBlock = pblock->hashPrevBlock;
genesis 3001 tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
genesis 3002 tmp.block.nTime = pblock->nTime;
genesis 3003 tmp.block.nBits = pblock->nBits;
genesis 3004 tmp.block.nNonce = pblock->nNonce;
genesis 3005
genesis 3006 FormatHashBlocks(&tmp.block, sizeof(tmp.block));
genesis 3007 FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
genesis 3008
genesis 3009
genesis 3010 for (int i = 0; i < sizeof(tmp)/4; i++)
genesis 3011 ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
genesis 3012
genesis 3013
genesis 3014 SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
genesis 3015
genesis 3016 memcpy(pdata, &tmp.block, 128);
genesis 3017 memcpy(phash1, &tmp.hash1, 64);
genesis 3018 }
genesis 3019
genesis 3020
genesis 3021 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
genesis 3022 {
genesis 3023 uint256 hash = pblock->GetHash();
genesis 3024 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis 3025
genesis 3026 if (hash > hashTarget)
genesis 3027 return false;
genesis 3028
genesis 3029
genesis 3030 printf("BitcoinMiner:\n");
genesis 3031 printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
genesis 3032 pblock->print();
genesis 3033 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis 3034 printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
genesis 3035
genesis 3036
genesis 3037 CRITICAL_BLOCK(cs_main)
genesis 3038 {
genesis 3039 if (pblock->hashPrevBlock != hashBestChain)
genesis 3040 return error("BitcoinMiner : generated block is stale");
genesis 3041
genesis 3042
genesis 3043 reservekey.KeepKey();
genesis 3044
genesis 3045
genesis 3046 CRITICAL_BLOCK(wallet.cs_wallet)
genesis 3047 wallet.mapRequestCount[pblock->GetHash()] = 0;
genesis 3048
genesis 3049
genesis 3050 if (!ProcessBlock(NULL, pblock))
genesis 3051 return error("BitcoinMiner : ProcessBlock, block not accepted");
genesis 3052 }
genesis 3053
genesis 3054 return true;
genesis 3055 }
genesis 3056
genesis 3057 void static ThreadBitcoinMiner(void* parg);
genesis 3058
genesis 3059 void static BitcoinMiner(CWallet *pwallet)
genesis 3060 {
genesis 3061 printf("BitcoinMiner started\n");
genesis 3062 SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis 3063
genesis 3064
genesis 3065 CReserveKey reservekey(pwallet);
genesis 3066 unsigned int nExtraNonce = 0;
genesis 3067
genesis 3068 while (fGenerateBitcoins)
genesis 3069 {
genesis 3070 if (AffinityBugWorkaround(ThreadBitcoinMiner))
genesis 3071 return;
genesis 3072 if (fShutdown)
genesis 3073 return;
genesis 3074 while (vNodes.empty() || IsInitialBlockDownload())
genesis 3075 {
genesis 3076 Sleep(1000);
genesis 3077 if (fShutdown)
genesis 3078 return;
genesis 3079 if (!fGenerateBitcoins)
genesis 3080 return;
genesis 3081 }
genesis 3082
genesis 3083
genesis 3084
genesis 3085
genesis 3086
genesis 3087 unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
genesis 3088 CBlockIndex* pindexPrev = pindexBest;
genesis 3089
genesis 3090 auto_ptr<CBlock> pblock(CreateNewBlock(reservekey));
genesis 3091 if (!pblock.get())
genesis 3092 return;
genesis 3093 IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
genesis 3094
genesis 3095 printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
genesis 3096
genesis 3097
genesis 3098
genesis 3099
genesis 3100
genesis 3101 char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
genesis 3102 char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
genesis 3103 char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
genesis 3104
genesis 3105 FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
genesis 3106
genesis 3107 unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
genesis 3108 unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
genesis 3109
genesis 3110
genesis 3111
genesis 3112
genesis 3113
genesis 3114 int64 nStart = GetTime();
genesis 3115 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis 3116 uint256 hashbuf[2];
genesis 3117 uint256& hash = *alignup<16>(hashbuf);
genesis 3118 loop
genesis 3119 {
genesis 3120 unsigned int nHashesDone = 0;
genesis 3121 unsigned int nNonceFound;
genesis 3122
genesis 3123
genesis 3124 nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
genesis 3125 (char*)&hash, nHashesDone);
genesis 3126
genesis 3127
genesis 3128 if (nNonceFound != -1)
genesis 3129 {
genesis 3130 for (int i = 0; i < sizeof(hash)/4; i++)
genesis 3131 ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
genesis 3132
genesis 3133 if (hash <= hashTarget)
genesis 3134 {
genesis 3135
genesis 3136 pblock->nNonce = ByteReverse(nNonceFound);
genesis 3137 assert(hash == pblock->GetHash());
genesis 3138
genesis 3139 SetThreadPriority(THREAD_PRIORITY_NORMAL);
genesis 3140 CheckWork(pblock.get(), *pwalletMain, reservekey);
genesis 3141 SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis 3142 break;
genesis 3143 }
genesis 3144 }
genesis 3145
genesis 3146
genesis 3147 static int64 nHashCounter;
genesis 3148 if (nHPSTimerStart == 0)
genesis 3149 {
genesis 3150 nHPSTimerStart = GetTimeMillis();
genesis 3151 nHashCounter = 0;
genesis 3152 }
genesis 3153 else
genesis 3154 nHashCounter += nHashesDone;
genesis 3155 if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis 3156 {
genesis 3157 static CCriticalSection cs;
genesis 3158 CRITICAL_BLOCK(cs)
genesis 3159 {
genesis 3160 if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis 3161 {
genesis 3162 dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
genesis 3163 nHPSTimerStart = GetTimeMillis();
genesis 3164 nHashCounter = 0;
genesis 3165 string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
genesis 3166 UIThreadCall(boost::bind(CalledSetStatusBar, strStatus, 0));
genesis 3167 static int64 nLogTime;
genesis 3168 if (GetTime() - nLogTime > 30 * 60)
genesis 3169 {
genesis 3170 nLogTime = GetTime();
genesis 3171 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis 3172 printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
genesis 3173 }
genesis 3174 }
genesis 3175 }
genesis 3176 }
genesis 3177
genesis 3178
genesis 3179 if (fShutdown)
genesis 3180 return;
genesis 3181 if (!fGenerateBitcoins)
genesis 3182 return;
genesis 3183 if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
genesis 3184 return;
genesis 3185 if (vNodes.empty())
genesis 3186 break;
genesis 3187 if (nBlockNonce >= 0xffff0000)
genesis 3188 break;
genesis 3189 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
genesis 3190 break;
genesis 3191 if (pindexPrev != pindexBest)
genesis 3192 break;
genesis 3193
genesis 3194
genesis 3195 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis 3196 nBlockTime = ByteReverse(pblock->nTime);
genesis 3197 }
genesis 3198 }
genesis 3199 }
genesis 3200
genesis 3201 void static ThreadBitcoinMiner(void* parg)
genesis 3202 {
genesis 3203 CWallet* pwallet = (CWallet*)parg;
genesis 3204 try
genesis 3205 {
genesis 3206 vnThreadsRunning[3]++;
genesis 3207 BitcoinMiner(pwallet);
genesis 3208 vnThreadsRunning[3]--;
genesis 3209 }
genesis 3210 catch (std::exception& e) {
genesis 3211 vnThreadsRunning[3]--;
genesis 3212 PrintException(&e, "ThreadBitcoinMiner()");
genesis 3213 } catch (...) {
genesis 3214 vnThreadsRunning[3]--;
genesis 3215 PrintException(NULL, "ThreadBitcoinMiner()");
genesis 3216 }
genesis 3217 UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
genesis 3218 nHPSTimerStart = 0;
genesis 3219 if (vnThreadsRunning[3] == 0)
genesis 3220 dHashesPerSec = 0;
genesis 3221 printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
genesis 3222 }
genesis 3223
genesis 3224
genesis 3225 void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
genesis 3226 {
genesis 3227 if (fGenerateBitcoins != fGenerate)
genesis 3228 {
genesis 3229 fGenerateBitcoins = fGenerate;
genesis 3230 WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
genesis 3231 MainFrameRepaint();
genesis 3232 }
genesis 3233 if (fGenerateBitcoins)
genesis 3234 {
genesis 3235 int nProcessors = boost::thread::hardware_concurrency();
genesis 3236 printf("%d processors\n", nProcessors);
genesis 3237 if (nProcessors < 1)
genesis 3238 nProcessors = 1;
genesis 3239 if (fLimitProcessors && nProcessors > nLimitProcessors)
genesis 3240 nProcessors = nLimitProcessors;
genesis 3241 int nAddThreads = nProcessors - vnThreadsRunning[3];
genesis 3242 printf("Starting %d BitcoinMiner threads\n", nAddThreads);
genesis 3243 for (int i = 0; i < nAddThreads; i++)
genesis 3244 {
genesis 3245 if (!CreateThread(ThreadBitcoinMiner, pwallet))
genesis 3246 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
genesis 3247 Sleep(10);
genesis 3248 }
genesis 3249 }
genesis 3250 }