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