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
bitcoin-asciilife... 1725
genesis 1726
genesis 1727
genesis 1728 string GetWarnings(string strFor)
genesis 1729 {
genesis 1730 int nPriority = 0;
genesis 1731 string strStatusBar;
genesis 1732 string strRPC;
genesis 1733 if (GetBoolArg("-testsafemode"))
genesis 1734 strRPC = "test";
genesis 1735
genesis 1736
genesis 1737 if (strMiscWarning != "")
genesis 1738 {
genesis 1739 nPriority = 1000;
genesis 1740 strStatusBar = strMiscWarning;
genesis 1741 }
genesis 1742
genesis 1743
genesis 1744 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
genesis 1745 {
genesis 1746 nPriority = 2000;
genesis 1747 strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.";
genesis 1748 }
genesis 1749
genesis 1750 if (strFor == "statusbar")
genesis 1751 return strStatusBar;
genesis 1752 else if (strFor == "rpc")
genesis 1753 return strRPC;
genesis 1754 assert(!"GetWarnings() : invalid parameter");
genesis 1755 return "error";
genesis 1756 }
genesis 1757
genesis 1758
genesis 1759
genesis 1760
genesis 1761
genesis 1762
genesis 1763
genesis 1764
genesis 1765 bool static AlreadyHave(CTxDB& txdb, const CInv& inv)
genesis 1766 {
genesis 1767 switch (inv.type)
genesis 1768 {
genesis 1769 case MSG_TX: return mapTransactions.count(inv.hash) || mapOrphanTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
genesis 1770 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
genesis 1771 }
genesis 1772
genesis 1773 return true;
genesis 1774 }
genesis 1775
genesis 1776
genesis 1777
genesis 1778
genesis 1779
genesis 1780
genesis 1781
genesis 1782 unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
genesis 1783
genesis 1784
genesis 1785 bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
genesis 1786 {
genesis 1787 static map<unsigned int, vector<unsigned char> > mapReuseKey;
genesis 1788 RandAddSeedPerfmon();
genesis 1789 if (fDebug) {
genesis 1790 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
genesis 1791 printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
genesis 1792 }
genesis 1793 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
genesis 1794 {
genesis 1795 printf("dropmessagestest DROPPING RECV MESSAGE\n");
genesis 1796 return true;
genesis 1797 }
genesis 1798
genesis 1799
genesis 1800
genesis 1801
genesis 1802
genesis 1803 if (strCommand == "version")
genesis 1804 {
genesis 1805
genesis 1806 if (pfrom->nVersion != 0)
genesis 1807 {
genesis 1808 pfrom->Misbehaving(1);
genesis 1809 return false;
genesis 1810 }
genesis 1811
genesis 1812 int64 nTime;
genesis 1813 CAddress addrMe;
genesis 1814 CAddress addrFrom;
genesis 1815 uint64 nNonce = 1;
genesis 1816 vRecv >> pfrom->nVersion >> pfrom->nServices >> nTime >> addrMe;
genesis 1817 if (pfrom->nVersion == 10300)
genesis 1818 pfrom->nVersion = 300;
genesis 1819 if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis 1820 vRecv >> addrFrom >> nNonce;
genesis 1821 if (pfrom->nVersion >= 106 && !vRecv.empty())
genesis 1822 vRecv >> pfrom->strSubVer;
genesis 1823 if (pfrom->nVersion >= 209 && !vRecv.empty())
genesis 1824 vRecv >> pfrom->nStartingHeight;
genesis 1825
genesis 1826 if (pfrom->nVersion == 0)
genesis 1827 return false;
genesis 1828
genesis 1829
genesis 1830 if (nNonce == nLocalHostNonce && nNonce > 1)
genesis 1831 {
genesis 1832 printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
genesis 1833 pfrom->fDisconnect = true;
genesis 1834 return true;
genesis 1835 }
genesis 1836
genesis 1837
genesis 1838 if (pfrom->fInbound)
genesis 1839 pfrom->PushVersion();
genesis 1840
genesis 1841 pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
genesis 1842
genesis 1843 AddTimeData(pfrom->addr.ip, nTime);
genesis 1844
genesis 1845
genesis 1846 if (pfrom->nVersion >= 209)
genesis 1847 pfrom->PushMessage("verack");
genesis 1848 pfrom->vSend.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1849 if (pfrom->nVersion < 209)
genesis 1850 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1851
genesis 1852 if (!pfrom->fInbound)
genesis 1853 {
genesis 1854
genesis 1855 if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis 1856 {
genesis 1857 CAddress addr(addrLocalHost);
genesis 1858 addr.nTime = GetAdjustedTime();
genesis 1859 pfrom->PushAddress(addr);
genesis 1860 }
genesis 1861
genesis 1862
genesis 1863 if (pfrom->nVersion >= 31402 || mapAddresses.size() < 1000)
genesis 1864 {
genesis 1865 pfrom->PushMessage("getaddr");
genesis 1866 pfrom->fGetAddr = true;
genesis 1867 }
genesis 1868 }
genesis 1869
genesis 1870
genesis 1871 static int nAskedForBlocks;
genesis 1872 if (!pfrom->fClient &&
genesis 1873 (pfrom->nVersion < 32000 || pfrom->nVersion >= 32400) &&
genesis 1874 (nAskedForBlocks < 1 || vNodes.size() <= 1))
genesis 1875 {
genesis 1876 nAskedForBlocks++;
genesis 1877 pfrom->PushGetBlocks(pindexBest, uint256(0));
genesis 1878 }
genesis 1879
genesis 1880 pfrom->fSuccessfullyConnected = true;
genesis 1881
genesis 1882 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
genesis 1883
genesis 1884 cPeerBlockCounts.input(pfrom->nStartingHeight);
genesis 1885 }
genesis 1886
genesis 1887
genesis 1888 else if (pfrom->nVersion == 0)
genesis 1889 {
genesis 1890
genesis 1891 pfrom->Misbehaving(1);
genesis 1892 return false;
genesis 1893 }
genesis 1894
genesis 1895
genesis 1896 else if (strCommand == "verack")
genesis 1897 {
genesis 1898 pfrom->vRecv.SetVersion(min(pfrom->nVersion, VERSION));
genesis 1899 }
genesis 1900
genesis 1901
genesis 1902 else if (strCommand == "addr")
genesis 1903 {
genesis 1904 vector<CAddress> vAddr;
genesis 1905 vRecv >> vAddr;
genesis 1906
genesis 1907
genesis 1908 if (pfrom->nVersion < 209)
genesis 1909 return true;
genesis 1910 if (pfrom->nVersion < 31402 && mapAddresses.size() > 1000)
genesis 1911 return true;
genesis 1912 if (vAddr.size() > 1000)
genesis 1913 {
genesis 1914 pfrom->Misbehaving(20);
genesis 1915 return error("message addr size() = %d", vAddr.size());
genesis 1916 }
genesis 1917
genesis 1918
genesis 1919 CAddrDB addrDB;
genesis 1920 addrDB.TxnBegin();
genesis 1921 int64 nNow = GetAdjustedTime();
genesis 1922 int64 nSince = nNow - 10 * 60;
genesis 1923 BOOST_FOREACH(CAddress& addr, vAddr)
genesis 1924 {
genesis 1925 if (fShutdown)
genesis 1926 return true;
genesis 1927
genesis 1928 if (!addr.IsIPv4())
genesis 1929 continue;
genesis 1930 if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
genesis 1931 addr.nTime = nNow - 5 * 24 * 60 * 60;
genesis 1932 AddAddress(addr, 2 * 60 * 60, &addrDB);
genesis 1933 pfrom->AddAddressKnown(addr);
genesis 1934 if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable())
genesis 1935 {
genesis 1936
genesis 1937 CRITICAL_BLOCK(cs_vNodes)
genesis 1938 {
genesis 1939
genesis 1940
genesis 1941 static uint256 hashSalt;
genesis 1942 if (hashSalt == 0)
genesis 1943 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis 1944 uint256 hashRand = hashSalt ^ (((int64)addr.ip)<<32) ^ ((GetTime()+addr.ip)/(24*60*60));
genesis 1945 hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis 1946 multimap<uint256, CNode*> mapMix;
genesis 1947 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 1948 {
genesis 1949 if (pnode->nVersion < 31402)
genesis 1950 continue;
genesis 1951 unsigned int nPointer;
genesis 1952 memcpy(&nPointer, &pnode, sizeof(nPointer));
genesis 1953 uint256 hashKey = hashRand ^ nPointer;
genesis 1954 hashKey = Hash(BEGIN(hashKey), END(hashKey));
genesis 1955 mapMix.insert(make_pair(hashKey, pnode));
genesis 1956 }
genesis 1957 int nRelayNodes = 2;
genesis 1958 for (multimap<uint256, CNode*>::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi)
genesis 1959 ((*mi).second)->PushAddress(addr);
genesis 1960 }
genesis 1961 }
genesis 1962 }
genesis 1963 addrDB.TxnCommit();
genesis 1964 if (vAddr.size() < 1000)
genesis 1965 pfrom->fGetAddr = false;
genesis 1966 }
genesis 1967
genesis 1968
genesis 1969 else if (strCommand == "inv")
genesis 1970 {
genesis 1971 vector<CInv> vInv;
genesis 1972 vRecv >> vInv;
genesis 1973 if (vInv.size() > 50000)
genesis 1974 {
genesis 1975 pfrom->Misbehaving(20);
genesis 1976 return error("message inv size() = %d", vInv.size());
genesis 1977 }
genesis 1978
genesis 1979 CTxDB txdb("r");
genesis 1980 BOOST_FOREACH(const CInv& inv, vInv)
genesis 1981 {
genesis 1982 if (fShutdown)
genesis 1983 return true;
genesis 1984 pfrom->AddInventoryKnown(inv);
genesis 1985
genesis 1986 bool fAlreadyHave = AlreadyHave(txdb, inv);
genesis 1987 if (fDebug)
genesis 1988 printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
genesis 1989
genesis 1990 if (!fAlreadyHave)
genesis 1991 pfrom->AskFor(inv);
genesis 1992 else if (inv.type == MSG_BLOCK && mapOrphanBlocks.count(inv.hash))
genesis 1993 pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(mapOrphanBlocks[inv.hash]));
genesis 1994
genesis 1995
genesis 1996 Inventory(inv.hash);
genesis 1997 }
genesis 1998 }
genesis 1999
genesis 2000
genesis 2001 else if (strCommand == "getdata")
genesis 2002 {
genesis 2003 vector<CInv> vInv;
genesis 2004 vRecv >> vInv;
genesis 2005 if (vInv.size() > 50000)
genesis 2006 {
genesis 2007 pfrom->Misbehaving(20);
genesis 2008 return error("message getdata size() = %d", vInv.size());
genesis 2009 }
genesis 2010
genesis 2011 BOOST_FOREACH(const CInv& inv, vInv)
genesis 2012 {
genesis 2013 if (fShutdown)
genesis 2014 return true;
genesis 2015 printf("received getdata for: %s\n", inv.ToString().c_str());
genesis 2016
genesis 2017 if (inv.type == MSG_BLOCK)
genesis 2018 {
genesis 2019
genesis 2020 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash);
genesis 2021 if (mi != mapBlockIndex.end())
genesis 2022 {
genesis 2023 CBlock block;
genesis 2024 block.ReadFromDisk((*mi).second);
genesis 2025 pfrom->PushMessage("block", block);
genesis 2026
genesis 2027
genesis 2028 if (inv.hash == pfrom->hashContinue)
genesis 2029 {
genesis 2030
genesis 2031
genesis 2032
genesis 2033 vector<CInv> vInv;
genesis 2034 vInv.push_back(CInv(MSG_BLOCK, hashBestChain));
genesis 2035 pfrom->PushMessage("inv", vInv);
genesis 2036 pfrom->hashContinue = 0;
genesis 2037 }
genesis 2038 }
genesis 2039 }
genesis 2040 else if (inv.IsKnownType())
genesis 2041 {
genesis 2042
genesis 2043 CRITICAL_BLOCK(cs_mapRelay)
genesis 2044 {
genesis 2045 map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
genesis 2046 if (mi != mapRelay.end())
genesis 2047 pfrom->PushMessage(inv.GetCommand(), (*mi).second);
genesis 2048 }
genesis 2049 }
genesis 2050
genesis 2051
genesis 2052 Inventory(inv.hash);
genesis 2053 }
genesis 2054 }
genesis 2055
genesis 2056
genesis 2057 else if (strCommand == "getblocks")
genesis 2058 {
genesis 2059 CBlockLocator locator;
genesis 2060 uint256 hashStop;
genesis 2061 vRecv >> locator >> hashStop;
genesis 2062
genesis 2063
genesis 2064 CBlockIndex* pindex = locator.GetBlockIndex();
genesis 2065
genesis 2066
genesis 2067 if (pindex)
genesis 2068 pindex = pindex->pnext;
genesis 2069 int nLimit = 500 + locator.GetDistanceBack();
genesis 2070 unsigned int nBytes = 0;
genesis 2071 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis 2072 for (; pindex; pindex = pindex->pnext)
genesis 2073 {
genesis 2074 if (pindex->GetBlockHash() == hashStop)
genesis 2075 {
genesis 2076 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis 2077 break;
genesis 2078 }
genesis 2079 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
genesis 2080 CBlock block;
genesis 2081 block.ReadFromDisk(pindex, true);
genesis 2082 nBytes += block.GetSerializeSize(SER_NETWORK);
genesis 2083 if (--nLimit <= 0 || nBytes >= SendBufferSize()/2)
genesis 2084 {
genesis 2085
genesis 2086
genesis 2087 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
genesis 2088 pfrom->hashContinue = pindex->GetBlockHash();
genesis 2089 break;
genesis 2090 }
genesis 2091 }
genesis 2092 }
genesis 2093
genesis 2094
genesis 2095 else if (strCommand == "getheaders")
genesis 2096 {
genesis 2097 CBlockLocator locator;
genesis 2098 uint256 hashStop;
genesis 2099 vRecv >> locator >> hashStop;
genesis 2100
genesis 2101 CBlockIndex* pindex = NULL;
genesis 2102 if (locator.IsNull())
genesis 2103 {
genesis 2104
genesis 2105 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop);
genesis 2106 if (mi == mapBlockIndex.end())
genesis 2107 return true;
genesis 2108 pindex = (*mi).second;
genesis 2109 }
genesis 2110 else
genesis 2111 {
genesis 2112
genesis 2113 pindex = locator.GetBlockIndex();
genesis 2114 if (pindex)
genesis 2115 pindex = pindex->pnext;
genesis 2116 }
genesis 2117
genesis 2118 vector<CBlock> vHeaders;
genesis 2119 int nLimit = 2000 + locator.GetDistanceBack();
genesis 2120 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
genesis 2121 for (; pindex; pindex = pindex->pnext)
genesis 2122 {
genesis 2123 vHeaders.push_back(pindex->GetBlockHeader());
genesis 2124 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
genesis 2125 break;
genesis 2126 }
genesis 2127 pfrom->PushMessage("headers", vHeaders);
genesis 2128 }
genesis 2129
genesis 2130
genesis 2131 else if (strCommand == "tx")
genesis 2132 {
genesis 2133 vector<uint256> vWorkQueue;
genesis 2134 CDataStream vMsg(vRecv);
genesis 2135 CTransaction tx;
genesis 2136 vRecv >> tx;
genesis 2137
genesis 2138 CInv inv(MSG_TX, tx.GetHash());
genesis 2139 pfrom->AddInventoryKnown(inv);
genesis 2140
genesis 2141 bool fMissingInputs = false;
genesis 2142 if (tx.AcceptToMemoryPool(true, &fMissingInputs))
genesis 2143 {
genesis 2144 SyncWithWallets(tx, NULL, true);
genesis 2145 RelayMessage(inv, vMsg);
genesis 2146 mapAlreadyAskedFor.erase(inv);
genesis 2147 vWorkQueue.push_back(inv.hash);
genesis 2148
genesis 2149
genesis 2150 for (int i = 0; i < vWorkQueue.size(); i++)
genesis 2151 {
genesis 2152 uint256 hashPrev = vWorkQueue[i];
genesis 2153 for (multimap<uint256, CDataStream*>::iterator mi = mapOrphanTransactionsByPrev.lower_bound(hashPrev);
genesis 2154 mi != mapOrphanTransactionsByPrev.upper_bound(hashPrev);
genesis 2155 ++mi)
genesis 2156 {
genesis 2157 const CDataStream& vMsg = *((*mi).second);
genesis 2158 CTransaction tx;
genesis 2159 CDataStream(vMsg) >> tx;
genesis 2160 CInv inv(MSG_TX, tx.GetHash());
genesis 2161
genesis 2162 if (tx.AcceptToMemoryPool(true))
genesis 2163 {
genesis 2164 printf(" accepted orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis 2165 SyncWithWallets(tx, NULL, true);
genesis 2166 RelayMessage(inv, vMsg);
genesis 2167 mapAlreadyAskedFor.erase(inv);
genesis 2168 vWorkQueue.push_back(inv.hash);
genesis 2169 }
genesis 2170 }
genesis 2171 }
genesis 2172
genesis 2173 BOOST_FOREACH(uint256 hash, vWorkQueue)
genesis 2174 EraseOrphanTx(hash);
genesis 2175 }
genesis 2176 else if (fMissingInputs)
genesis 2177 {
genesis 2178 printf("storing orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
genesis 2179 AddOrphanTx(vMsg);
genesis 2180
genesis 2181
genesis 2182 int nEvicted = LimitOrphanTxSize(MAX_ORPHAN_TRANSACTIONS);
genesis 2183 if (nEvicted > 0)
genesis 2184 printf("mapOrphan overflow, removed %d tx\n", nEvicted);
genesis 2185 }
genesis 2186 if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
genesis 2187 }
genesis 2188
genesis 2189
genesis 2190 else if (strCommand == "block")
genesis 2191 {
genesis 2192 CBlock block;
genesis 2193 vRecv >> block;
genesis 2194
genesis 2195 printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
genesis 2196
genesis 2197
genesis 2198 CInv inv(MSG_BLOCK, block.GetHash());
genesis 2199 pfrom->AddInventoryKnown(inv);
genesis 2200
genesis 2201 if (ProcessBlock(pfrom, &block))
genesis 2202 mapAlreadyAskedFor.erase(inv);
genesis 2203 if (block.nDoS) pfrom->Misbehaving(block.nDoS);
genesis 2204 }
genesis 2205
genesis 2206
genesis 2207 else if (strCommand == "getaddr")
genesis 2208 {
genesis 2209
genesis 2210 pfrom->vAddrToSend.clear();
genesis 2211 int64 nSince = GetAdjustedTime() - 3 * 60 * 60;
genesis 2212 CRITICAL_BLOCK(cs_mapAddresses)
genesis 2213 {
genesis 2214 unsigned int nCount = 0;
genesis 2215 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis 2216 {
genesis 2217 const CAddress& addr = item.second;
genesis 2218 if (addr.nTime > nSince)
genesis 2219 nCount++;
genesis 2220 }
genesis 2221 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
genesis 2222 {
genesis 2223 const CAddress& addr = item.second;
genesis 2224 if (addr.nTime > nSince && GetRand(nCount) < 2500)
genesis 2225 pfrom->PushAddress(addr);
genesis 2226 }
genesis 2227 }
genesis 2228 }
genesis 2229
genesis 2230
genesis 2231 else if (strCommand == "checkorder")
genesis 2232 {
genesis 2233 uint256 hashReply;
genesis 2234 vRecv >> hashReply;
genesis 2235
genesis 2236 if (!GetBoolArg("-allowreceivebyip"))
genesis 2237 {
genesis 2238 pfrom->PushMessage("reply", hashReply, (int)2, string(""));
genesis 2239 return true;
genesis 2240 }
genesis 2241
genesis 2242 CWalletTx order;
genesis 2243 vRecv >> order;
genesis 2244
genesis 2245
genesis 2246
genesis 2247
genesis 2248 if (!mapReuseKey.count(pfrom->addr.ip))
genesis 2249 pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
genesis 2250
genesis 2251
genesis 2252 CScript scriptPubKey;
genesis 2253 scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG;
genesis 2254 pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey);
genesis 2255 }
genesis 2256
genesis 2257
genesis 2258 else if (strCommand == "reply")
genesis 2259 {
genesis 2260 uint256 hashReply;
genesis 2261 vRecv >> hashReply;
genesis 2262
genesis 2263 CRequestTracker tracker;
genesis 2264 CRITICAL_BLOCK(pfrom->cs_mapRequests)
genesis 2265 {
genesis 2266 map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
genesis 2267 if (mi != pfrom->mapRequests.end())
genesis 2268 {
genesis 2269 tracker = (*mi).second;
genesis 2270 pfrom->mapRequests.erase(mi);
genesis 2271 }
genesis 2272 }
genesis 2273 if (!tracker.IsNull())
genesis 2274 tracker.fn(tracker.param1, vRecv);
genesis 2275 }
genesis 2276
genesis 2277
genesis 2278 else if (strCommand == "ping")
genesis 2279 {
genesis 2280 }
genesis 2281
genesis 2282
genesis 2283 else
genesis 2284 {
genesis 2285
genesis 2286 }
genesis 2287
genesis 2288
genesis 2289
genesis 2290 if (pfrom->fNetworkNode)
genesis 2291 if (strCommand == "version" || strCommand == "addr" || strCommand == "inv" || strCommand == "getdata" || strCommand == "ping")
genesis 2292 AddressCurrentlyConnected(pfrom->addr);
genesis 2293
genesis 2294
genesis 2295 return true;
genesis 2296 }
genesis 2297
genesis 2298 bool ProcessMessages(CNode* pfrom)
genesis 2299 {
genesis 2300 CDataStream& vRecv = pfrom->vRecv;
genesis 2301 if (vRecv.empty())
genesis 2302 return true;
genesis 2303
genesis 2304
genesis 2305
genesis 2306
genesis 2307
genesis 2308
genesis 2309
genesis 2310
genesis 2311
genesis 2312
genesis 2313
genesis 2314
genesis 2315 loop
genesis 2316 {
genesis 2317
genesis 2318 CDataStream::iterator pstart = search(vRecv.begin(), vRecv.end(), BEGIN(pchMessageStart), END(pchMessageStart));
genesis 2319 int nHeaderSize = vRecv.GetSerializeSize(CMessageHeader());
genesis 2320 if (vRecv.end() - pstart < nHeaderSize)
genesis 2321 {
genesis 2322 if (vRecv.size() > nHeaderSize)
genesis 2323 {
genesis 2324 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
genesis 2325 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
genesis 2326 }
genesis 2327 break;
genesis 2328 }
genesis 2329 if (pstart - vRecv.begin() > 0)
genesis 2330 printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
genesis 2331 vRecv.erase(vRecv.begin(), pstart);
genesis 2332
genesis 2333
genesis 2334 vector<char> vHeaderSave(vRecv.begin(), vRecv.begin() + nHeaderSize);
genesis 2335 CMessageHeader hdr;
genesis 2336 vRecv >> hdr;
genesis 2337 if (!hdr.IsValid())
genesis 2338 {
genesis 2339 printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
genesis 2340 continue;
genesis 2341 }
genesis 2342 string strCommand = hdr.GetCommand();
genesis 2343
genesis 2344
genesis 2345 unsigned int nMessageSize = hdr.nMessageSize;
genesis 2346 if (nMessageSize > MAX_SIZE)
genesis 2347 {
genesis 2348 printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
genesis 2349 continue;
genesis 2350 }
genesis 2351 if (nMessageSize > vRecv.size())
genesis 2352 {
genesis 2353
genesis 2354 vRecv.insert(vRecv.begin(), vHeaderSave.begin(), vHeaderSave.end());
genesis 2355 break;
genesis 2356 }
genesis 2357
genesis 2358
genesis 2359 if (vRecv.GetVersion() >= 209)
genesis 2360 {
genesis 2361 uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
genesis 2362 unsigned int nChecksum = 0;
genesis 2363 memcpy(&nChecksum, &hash, sizeof(nChecksum));
genesis 2364 if (nChecksum != hdr.nChecksum)
genesis 2365 {
genesis 2366 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
genesis 2367 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
genesis 2368 continue;
genesis 2369 }
genesis 2370 }
genesis 2371
genesis 2372
genesis 2373 CDataStream vMsg(vRecv.begin(), vRecv.begin() + nMessageSize, vRecv.nType, vRecv.nVersion);
genesis 2374 vRecv.ignore(nMessageSize);
genesis 2375
genesis 2376
genesis 2377 bool fRet = false;
genesis 2378 try
genesis 2379 {
genesis 2380 CRITICAL_BLOCK(cs_main)
genesis 2381 fRet = ProcessMessage(pfrom, strCommand, vMsg);
genesis 2382 if (fShutdown)
genesis 2383 return true;
genesis 2384 }
genesis 2385 catch (std::ios_base::failure& e)
genesis 2386 {
genesis 2387 if (strstr(e.what(), "end of data"))
genesis 2388 {
genesis 2389
genesis 2390 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 2391 }
genesis 2392 else if (strstr(e.what(), "size too large"))
genesis 2393 {
genesis 2394
genesis 2395 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
genesis 2396 }
genesis 2397 else
genesis 2398 {
genesis 2399 PrintExceptionContinue(&e, "ProcessMessage()");
genesis 2400 }
genesis 2401 }
genesis 2402 catch (std::exception& e) {
genesis 2403 PrintExceptionContinue(&e, "ProcessMessage()");
genesis 2404 } catch (...) {
genesis 2405 PrintExceptionContinue(NULL, "ProcessMessage()");
genesis 2406 }
genesis 2407
genesis 2408 if (!fRet)
genesis 2409 printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
genesis 2410 }
genesis 2411
genesis 2412 vRecv.Compact();
genesis 2413 return true;
genesis 2414 }
genesis 2415
genesis 2416
genesis 2417 bool SendMessages(CNode* pto, bool fSendTrickle)
genesis 2418 {
genesis 2419 CRITICAL_BLOCK(cs_main)
genesis 2420 {
genesis 2421
genesis 2422 if (pto->nVersion == 0)
genesis 2423 return true;
genesis 2424
genesis 2425
genesis 2426 if (pto->nLastSend && GetTime() - pto->nLastSend > 30 * 60 && pto->vSend.empty())
genesis 2427 pto->PushMessage("ping");
genesis 2428
genesis 2429
genesis 2430 ResendWalletTransactions();
genesis 2431
genesis 2432
genesis 2433 static int64 nLastRebroadcast;
genesis 2434 if (GetTime() - nLastRebroadcast > 24 * 60 * 60)
genesis 2435 {
genesis 2436 nLastRebroadcast = GetTime();
genesis 2437 CRITICAL_BLOCK(cs_vNodes)
genesis 2438 {
genesis 2439 BOOST_FOREACH(CNode* pnode, vNodes)
genesis 2440 {
genesis 2441
genesis 2442 pnode->setAddrKnown.clear();
genesis 2443
genesis 2444
genesis 2445 if (addrLocalHost.IsRoutable() && !fUseProxy)
genesis 2446 {
genesis 2447 CAddress addr(addrLocalHost);
genesis 2448 addr.nTime = GetAdjustedTime();
genesis 2449 pnode->PushAddress(addr);
genesis 2450 }
genesis 2451 }
genesis 2452 }
genesis 2453 }
genesis 2454
genesis 2455
genesis 2456 static int64 nLastClear;
genesis 2457 if (nLastClear == 0)
genesis 2458 nLastClear = GetTime();
genesis 2459 if (GetTime() - nLastClear > 10 * 60 && vNodes.size() >= 3)
genesis 2460 {
genesis 2461 nLastClear = GetTime();
genesis 2462 CRITICAL_BLOCK(cs_mapAddresses)
genesis 2463 {
genesis 2464 CAddrDB addrdb;
genesis 2465 int64 nSince = GetAdjustedTime() - 14 * 24 * 60 * 60;
genesis 2466 for (map<vector<unsigned char>, CAddress>::iterator mi = mapAddresses.begin();
genesis 2467 mi != mapAddresses.end();)
genesis 2468 {
genesis 2469 const CAddress& addr = (*mi).second;
genesis 2470 if (addr.nTime < nSince)
genesis 2471 {
genesis 2472 if (mapAddresses.size() < 1000 || GetTime() > nLastClear + 20)
genesis 2473 break;
genesis 2474 addrdb.EraseAddress(addr);
genesis 2475 mapAddresses.erase(mi++);
genesis 2476 }
genesis 2477 else
genesis 2478 mi++;
genesis 2479 }
genesis 2480 }
genesis 2481 }
genesis 2482
genesis 2483
genesis 2484
genesis 2485
genesis 2486
genesis 2487 if (fSendTrickle)
genesis 2488 {
genesis 2489 vector<CAddress> vAddr;
genesis 2490 vAddr.reserve(pto->vAddrToSend.size());
genesis 2491 BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend)
genesis 2492 {
genesis 2493
genesis 2494 if (pto->setAddrKnown.insert(addr).second)
genesis 2495 {
genesis 2496 vAddr.push_back(addr);
genesis 2497
genesis 2498 if (vAddr.size() >= 1000)
genesis 2499 {
genesis 2500 pto->PushMessage("addr", vAddr);
genesis 2501 vAddr.clear();
genesis 2502 }
genesis 2503 }
genesis 2504 }
genesis 2505 pto->vAddrToSend.clear();
genesis 2506 if (!vAddr.empty())
genesis 2507 pto->PushMessage("addr", vAddr);
genesis 2508 }
genesis 2509
genesis 2510
genesis 2511
genesis 2512
genesis 2513
genesis 2514 vector<CInv> vInv;
genesis 2515 vector<CInv> vInvWait;
genesis 2516 CRITICAL_BLOCK(pto->cs_inventory)
genesis 2517 {
genesis 2518 vInv.reserve(pto->vInventoryToSend.size());
genesis 2519 vInvWait.reserve(pto->vInventoryToSend.size());
genesis 2520 BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend)
genesis 2521 {
genesis 2522 if (pto->setInventoryKnown.count(inv))
genesis 2523 continue;
genesis 2524
genesis 2525
genesis 2526 if (inv.type == MSG_TX && !fSendTrickle)
genesis 2527 {
genesis 2528
genesis 2529 static uint256 hashSalt;
genesis 2530 if (hashSalt == 0)
genesis 2531 RAND_bytes((unsigned char*)&hashSalt, sizeof(hashSalt));
genesis 2532 uint256 hashRand = inv.hash ^ hashSalt;
genesis 2533 hashRand = Hash(BEGIN(hashRand), END(hashRand));
genesis 2534 bool fTrickleWait = ((hashRand & 3) != 0);
genesis 2535
genesis 2536
genesis 2537 if (!fTrickleWait)
genesis 2538 {
genesis 2539 CWalletTx wtx;
genesis 2540 if (GetTransaction(inv.hash, wtx))
genesis 2541 if (wtx.fFromMe)
genesis 2542 fTrickleWait = true;
genesis 2543 }
genesis 2544
genesis 2545 if (fTrickleWait)
genesis 2546 {
genesis 2547 vInvWait.push_back(inv);
genesis 2548 continue;
genesis 2549 }
genesis 2550 }
genesis 2551
genesis 2552
genesis 2553 if (pto->setInventoryKnown.insert(inv).second)
genesis 2554 {
genesis 2555 vInv.push_back(inv);
genesis 2556 if (vInv.size() >= 1000)
genesis 2557 {
genesis 2558 pto->PushMessage("inv", vInv);
genesis 2559 vInv.clear();
genesis 2560 }
genesis 2561 }
genesis 2562 }
genesis 2563 pto->vInventoryToSend = vInvWait;
genesis 2564 }
genesis 2565 if (!vInv.empty())
genesis 2566 pto->PushMessage("inv", vInv);
genesis 2567
genesis 2568
genesis 2569
genesis 2570
genesis 2571
genesis 2572 vector<CInv> vGetData;
genesis 2573 int64 nNow = GetTime() * 1000000;
genesis 2574 CTxDB txdb("r");
genesis 2575 while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow)
genesis 2576 {
genesis 2577 const CInv& inv = (*pto->mapAskFor.begin()).second;
genesis 2578 if (!AlreadyHave(txdb, inv))
genesis 2579 {
genesis 2580 printf("sending getdata: %s\n", inv.ToString().c_str());
genesis 2581 vGetData.push_back(inv);
genesis 2582 if (vGetData.size() >= 1000)
genesis 2583 {
genesis 2584 pto->PushMessage("getdata", vGetData);
genesis 2585 vGetData.clear();
genesis 2586 }
genesis 2587 }
genesis 2588 mapAlreadyAskedFor[inv] = nNow;
genesis 2589 pto->mapAskFor.erase(pto->mapAskFor.begin());
genesis 2590 }
genesis 2591 if (!vGetData.empty())
genesis 2592 pto->PushMessage("getdata", vGetData);
genesis 2593
genesis 2594 }
genesis 2595 return true;
genesis 2596 }
genesis 2597
genesis 2598
genesis 2599
genesis 2600
genesis 2601
genesis 2602
genesis 2603
genesis 2604
genesis 2605
genesis 2606
genesis 2607
genesis 2608
genesis 2609
genesis 2610
genesis 2611
genesis 2612
genesis 2613
genesis 2614
genesis 2615
genesis 2616 int static FormatHashBlocks(void* pbuffer, unsigned int len)
genesis 2617 {
genesis 2618 unsigned char* pdata = (unsigned char*)pbuffer;
genesis 2619 unsigned int blocks = 1 + ((len + 8) / 64);
genesis 2620 unsigned char* pend = pdata + 64 * blocks;
genesis 2621 memset(pdata + len, 0, 64 * blocks - len);
genesis 2622 pdata[len] = 0x80;
genesis 2623 unsigned int bits = len * 8;
genesis 2624 pend[-1] = (bits >> 0) & 0xff;
genesis 2625 pend[-2] = (bits >> 8) & 0xff;
genesis 2626 pend[-3] = (bits >> 16) & 0xff;
genesis 2627 pend[-4] = (bits >> 24) & 0xff;
genesis 2628 return blocks;
genesis 2629 }
genesis 2630
genesis 2631 static const unsigned int pSHA256InitState[8] =
genesis 2632 {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
genesis 2633
genesis 2634 void SHA256Transform(void* pstate, void* pinput, const void* pinit)
genesis 2635 {
genesis 2636 SHA256_CTX ctx;
genesis 2637 unsigned char data[64];
genesis 2638
genesis 2639 SHA256_Init(&ctx);
genesis 2640
genesis 2641 for (int i = 0; i < 16; i++)
genesis 2642 ((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]);
genesis 2643
genesis 2644 for (int i = 0; i < 8; i++)
genesis 2645 ctx.h[i] = ((uint32_t*)pinit)[i];
genesis 2646
genesis 2647 SHA256_Update(&ctx, data, sizeof(data));
genesis 2648 for (int i = 0; i < 8; i++)
genesis 2649 ((uint32_t*)pstate)[i] = ctx.h[i];
genesis 2650 }
genesis 2651
genesis 2652
genesis 2653
genesis 2654
genesis 2655
genesis 2656
genesis 2657
genesis 2658
genesis 2659 unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone)
genesis 2660 {
genesis 2661 unsigned int& nNonce = *(unsigned int*)(pdata + 12);
genesis 2662 for (;;)
genesis 2663 {
genesis 2664
genesis 2665
genesis 2666
genesis 2667 nNonce++;
genesis 2668 SHA256Transform(phash1, pdata, pmidstate);
genesis 2669 SHA256Transform(phash, phash1, pSHA256InitState);
genesis 2670
genesis 2671
genesis 2672
genesis 2673 if (((unsigned short*)phash)[14] == 0)
genesis 2674 return nNonce;
genesis 2675
genesis 2676
genesis 2677 if ((nNonce & 0xffff) == 0)
genesis 2678 {
genesis 2679 nHashesDone = 0xffff+1;
genesis 2680 return -1;
genesis 2681 }
genesis 2682 }
genesis 2683 }
genesis 2684
genesis 2685
genesis 2686 class COrphan
genesis 2687 {
genesis 2688 public:
genesis 2689 CTransaction* ptx;
genesis 2690 set<uint256> setDependsOn;
genesis 2691 double dPriority;
genesis 2692
genesis 2693 COrphan(CTransaction* ptxIn)
genesis 2694 {
genesis 2695 ptx = ptxIn;
genesis 2696 dPriority = 0;
genesis 2697 }
genesis 2698
genesis 2699 void print() const
genesis 2700 {
genesis 2701 printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority);
genesis 2702 BOOST_FOREACH(uint256 hash, setDependsOn)
genesis 2703 printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
genesis 2704 }
genesis 2705 };
genesis 2706
genesis 2707
genesis 2708 CBlock* CreateNewBlock(CReserveKey& reservekey)
genesis 2709 {
genesis 2710 CBlockIndex* pindexPrev = pindexBest;
genesis 2711
genesis 2712
genesis 2713 auto_ptr<CBlock> pblock(new CBlock());
genesis 2714 if (!pblock.get())
genesis 2715 return NULL;
genesis 2716
genesis 2717
genesis 2718 CTransaction txNew;
genesis 2719 txNew.vin.resize(1);
genesis 2720 txNew.vin[0].prevout.SetNull();
genesis 2721 txNew.vout.resize(1);
genesis 2722 txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
genesis 2723
genesis 2724
genesis 2725 pblock->vtx.push_back(txNew);
genesis 2726
genesis 2727
genesis 2728 int64 nFees = 0;
genesis 2729 CRITICAL_BLOCK(cs_main)
genesis 2730 CRITICAL_BLOCK(cs_mapTransactions)
genesis 2731 {
genesis 2732 CTxDB txdb("r");
genesis 2733
genesis 2734
genesis 2735 list<COrphan> vOrphan;
genesis 2736 map<uint256, vector<COrphan*> > mapDependers;
genesis 2737 multimap<double, CTransaction*> mapPriority;
genesis 2738 for (map<uint256, CTransaction>::iterator mi = mapTransactions.begin(); mi != mapTransactions.end(); ++mi)
genesis 2739 {
genesis 2740 CTransaction& tx = (*mi).second;
genesis 2741 if (tx.IsCoinBase() || !tx.IsFinal())
genesis 2742 continue;
genesis 2743
genesis 2744 COrphan* porphan = NULL;
genesis 2745 double dPriority = 0;
genesis 2746 BOOST_FOREACH(const CTxIn& txin, tx.vin)
genesis 2747 {
genesis 2748
genesis 2749 CTransaction txPrev;
genesis 2750 CTxIndex txindex;
genesis 2751 if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
genesis 2752 {
genesis 2753
genesis 2754 if (!porphan)
genesis 2755 {
genesis 2756
genesis 2757 vOrphan.push_back(COrphan(&tx));
genesis 2758 porphan = &vOrphan.back();
genesis 2759 }
genesis 2760 mapDependers[txin.prevout.hash].push_back(porphan);
genesis 2761 porphan->setDependsOn.insert(txin.prevout.hash);
genesis 2762 continue;
genesis 2763 }
genesis 2764 int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
genesis 2765
genesis 2766
genesis 2767 int nConf = txindex.GetDepthInMainChain();
genesis 2768
genesis 2769 dPriority += (double)nValueIn * nConf;
genesis 2770
genesis 2771 if (fDebug && GetBoolArg("-printpriority"))
genesis 2772 printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
genesis 2773 }
genesis 2774
genesis 2775
genesis 2776 dPriority /= ::GetSerializeSize(tx, SER_NETWORK);
genesis 2777
genesis 2778 if (porphan)
genesis 2779 porphan->dPriority = dPriority;
genesis 2780 else
genesis 2781 mapPriority.insert(make_pair(-dPriority, &(*mi).second));
genesis 2782
genesis 2783 if (fDebug && GetBoolArg("-printpriority"))
genesis 2784 {
genesis 2785 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
genesis 2786 if (porphan)
genesis 2787 porphan->print();
genesis 2788 printf("\n");
genesis 2789 }
genesis 2790 }
genesis 2791
genesis 2792
genesis 2793 map<uint256, CTxIndex> mapTestPool;
genesis 2794 uint64 nBlockSize = 1000;
genesis 2795 int nBlockSigOps = 100;
genesis 2796 while (!mapPriority.empty())
genesis 2797 {
genesis 2798
genesis 2799 double dPriority = -(*mapPriority.begin()).first;
genesis 2800 CTransaction& tx = *(*mapPriority.begin()).second;
genesis 2801 mapPriority.erase(mapPriority.begin());
genesis 2802
genesis 2803
genesis 2804 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK);
genesis 2805 if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
genesis 2806 continue;
genesis 2807 int nTxSigOps = tx.GetSigOpCount();
genesis 2808 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
genesis 2809 continue;
genesis 2810
genesis 2811
genesis 2812 bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
genesis 2813 int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree);
genesis 2814
genesis 2815
genesis 2816
genesis 2817 map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
genesis 2818 bool fInvalid;
genesis 2819 if (!tx.ConnectInputs(txdb, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, nFees, false, true, nMinFee, fInvalid))
genesis 2820 continue;
genesis 2821 swap(mapTestPool, mapTestPoolTmp);
genesis 2822
genesis 2823
genesis 2824 pblock->vtx.push_back(tx);
genesis 2825 nBlockSize += nTxSize;
genesis 2826 nBlockSigOps += nTxSigOps;
genesis 2827
genesis 2828
genesis 2829 uint256 hash = tx.GetHash();
genesis 2830 if (mapDependers.count(hash))
genesis 2831 {
genesis 2832 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
genesis 2833 {
genesis 2834 if (!porphan->setDependsOn.empty())
genesis 2835 {
genesis 2836 porphan->setDependsOn.erase(hash);
genesis 2837 if (porphan->setDependsOn.empty())
genesis 2838 mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
genesis 2839 }
genesis 2840 }
genesis 2841 }
genesis 2842 }
genesis 2843 }
genesis 2844 pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
genesis 2845
genesis 2846
genesis 2847 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
genesis 2848 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis 2849 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis 2850 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock.get());
genesis 2851 pblock->nNonce = 0;
genesis 2852
genesis 2853 return pblock.release();
genesis 2854 }
genesis 2855
genesis 2856
genesis 2857 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
genesis 2858 {
genesis 2859
genesis 2860 static uint256 hashPrevBlock;
genesis 2861 if (hashPrevBlock != pblock->hashPrevBlock)
genesis 2862 {
genesis 2863 nExtraNonce = 0;
genesis 2864 hashPrevBlock = pblock->hashPrevBlock;
genesis 2865 }
genesis 2866 ++nExtraNonce;
genesis 2867 pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce);
genesis 2868 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
genesis 2869 }
genesis 2870
genesis 2871
genesis 2872 void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1)
genesis 2873 {
genesis 2874
genesis 2875
genesis 2876
genesis 2877 struct
genesis 2878 {
genesis 2879 struct unnamed2
genesis 2880 {
genesis 2881 int nVersion;
genesis 2882 uint256 hashPrevBlock;
genesis 2883 uint256 hashMerkleRoot;
genesis 2884 unsigned int nTime;
genesis 2885 unsigned int nBits;
genesis 2886 unsigned int nNonce;
genesis 2887 }
genesis 2888 block;
genesis 2889 unsigned char pchPadding0[64];
genesis 2890 uint256 hash1;
genesis 2891 unsigned char pchPadding1[64];
genesis 2892 }
genesis 2893 tmp;
genesis 2894 memset(&tmp, 0, sizeof(tmp));
genesis 2895
genesis 2896 tmp.block.nVersion = pblock->nVersion;
genesis 2897 tmp.block.hashPrevBlock = pblock->hashPrevBlock;
genesis 2898 tmp.block.hashMerkleRoot = pblock->hashMerkleRoot;
genesis 2899 tmp.block.nTime = pblock->nTime;
genesis 2900 tmp.block.nBits = pblock->nBits;
genesis 2901 tmp.block.nNonce = pblock->nNonce;
genesis 2902
genesis 2903 FormatHashBlocks(&tmp.block, sizeof(tmp.block));
genesis 2904 FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1));
genesis 2905
genesis 2906
genesis 2907 for (int i = 0; i < sizeof(tmp)/4; i++)
genesis 2908 ((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]);
genesis 2909
genesis 2910
genesis 2911 SHA256Transform(pmidstate, &tmp.block, pSHA256InitState);
genesis 2912
genesis 2913 memcpy(pdata, &tmp.block, 128);
genesis 2914 memcpy(phash1, &tmp.hash1, 64);
genesis 2915 }
genesis 2916
genesis 2917
genesis 2918 bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
genesis 2919 {
genesis 2920 uint256 hash = pblock->GetHash();
genesis 2921 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis 2922
genesis 2923 if (hash > hashTarget)
genesis 2924 return false;
genesis 2925
genesis 2926
genesis 2927 printf("BitcoinMiner:\n");
genesis 2928 printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
genesis 2929 pblock->print();
genesis 2930 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis 2931 printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
genesis 2932
genesis 2933
genesis 2934 CRITICAL_BLOCK(cs_main)
genesis 2935 {
genesis 2936 if (pblock->hashPrevBlock != hashBestChain)
genesis 2937 return error("BitcoinMiner : generated block is stale");
genesis 2938
genesis 2939
genesis 2940 reservekey.KeepKey();
genesis 2941
genesis 2942
genesis 2943 CRITICAL_BLOCK(wallet.cs_wallet)
genesis 2944 wallet.mapRequestCount[pblock->GetHash()] = 0;
genesis 2945
genesis 2946
genesis 2947 if (!ProcessBlock(NULL, pblock))
genesis 2948 return error("BitcoinMiner : ProcessBlock, block not accepted");
genesis 2949 }
genesis 2950
genesis 2951 return true;
genesis 2952 }
genesis 2953
genesis 2954 void static ThreadBitcoinMiner(void* parg);
genesis 2955
genesis 2956 void static BitcoinMiner(CWallet *pwallet)
genesis 2957 {
genesis 2958 printf("BitcoinMiner started\n");
genesis 2959 SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis 2960
genesis 2961
genesis 2962 CReserveKey reservekey(pwallet);
genesis 2963 unsigned int nExtraNonce = 0;
genesis 2964
genesis 2965 while (fGenerateBitcoins)
genesis 2966 {
genesis 2967 if (AffinityBugWorkaround(ThreadBitcoinMiner))
genesis 2968 return;
genesis 2969 if (fShutdown)
genesis 2970 return;
genesis 2971 while (vNodes.empty() || IsInitialBlockDownload())
genesis 2972 {
genesis 2973 Sleep(1000);
genesis 2974 if (fShutdown)
genesis 2975 return;
genesis 2976 if (!fGenerateBitcoins)
genesis 2977 return;
genesis 2978 }
genesis 2979
genesis 2980
genesis 2981
genesis 2982
genesis 2983
genesis 2984 unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
genesis 2985 CBlockIndex* pindexPrev = pindexBest;
genesis 2986
genesis 2987 auto_ptr<CBlock> pblock(CreateNewBlock(reservekey));
genesis 2988 if (!pblock.get())
genesis 2989 return;
genesis 2990 IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
genesis 2991
genesis 2992 printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
genesis 2993
genesis 2994
genesis 2995
genesis 2996
genesis 2997
genesis 2998 char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
genesis 2999 char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf);
genesis 3000 char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf);
genesis 3001
genesis 3002 FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);
genesis 3003
genesis 3004 unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
genesis 3005 unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);
genesis 3006
genesis 3007
genesis 3008
genesis 3009
genesis 3010
genesis 3011 int64 nStart = GetTime();
genesis 3012 uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
genesis 3013 uint256 hashbuf[2];
genesis 3014 uint256& hash = *alignup<16>(hashbuf);
genesis 3015 loop
genesis 3016 {
genesis 3017 unsigned int nHashesDone = 0;
genesis 3018 unsigned int nNonceFound;
genesis 3019
genesis 3020
genesis 3021 nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
genesis 3022 (char*)&hash, nHashesDone);
genesis 3023
genesis 3024
genesis 3025 if (nNonceFound != -1)
genesis 3026 {
genesis 3027 for (int i = 0; i < sizeof(hash)/4; i++)
genesis 3028 ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);
genesis 3029
genesis 3030 if (hash <= hashTarget)
genesis 3031 {
genesis 3032
genesis 3033 pblock->nNonce = ByteReverse(nNonceFound);
genesis 3034 assert(hash == pblock->GetHash());
genesis 3035
genesis 3036 SetThreadPriority(THREAD_PRIORITY_NORMAL);
genesis 3037 CheckWork(pblock.get(), *pwalletMain, reservekey);
genesis 3038 SetThreadPriority(THREAD_PRIORITY_LOWEST);
genesis 3039 break;
genesis 3040 }
genesis 3041 }
genesis 3042
genesis 3043
genesis 3044 static int64 nHashCounter;
genesis 3045 if (nHPSTimerStart == 0)
genesis 3046 {
genesis 3047 nHPSTimerStart = GetTimeMillis();
genesis 3048 nHashCounter = 0;
genesis 3049 }
genesis 3050 else
genesis 3051 nHashCounter += nHashesDone;
genesis 3052 if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis 3053 {
genesis 3054 static CCriticalSection cs;
genesis 3055 CRITICAL_BLOCK(cs)
genesis 3056 {
genesis 3057 if (GetTimeMillis() - nHPSTimerStart > 4000)
genesis 3058 {
genesis 3059 dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
genesis 3060 nHPSTimerStart = GetTimeMillis();
genesis 3061 nHashCounter = 0;
genesis 3062 string strStatus = strprintf(" %.0f khash/s", dHashesPerSec/1000.0);
genesis 3063 UIThreadCall(boost::bind(CalledSetStatusBar, strStatus, 0));
genesis 3064 static int64 nLogTime;
genesis 3065 if (GetTime() - nLogTime > 30 * 60)
genesis 3066 {
genesis 3067 nLogTime = GetTime();
genesis 3068 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
genesis 3069 printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[3], dHashesPerSec/1000.0);
genesis 3070 }
genesis 3071 }
genesis 3072 }
genesis 3073 }
genesis 3074
genesis 3075
genesis 3076 if (fShutdown)
genesis 3077 return;
genesis 3078 if (!fGenerateBitcoins)
genesis 3079 return;
genesis 3080 if (fLimitProcessors && vnThreadsRunning[3] > nLimitProcessors)
genesis 3081 return;
genesis 3082 if (vNodes.empty())
genesis 3083 break;
genesis 3084 if (nBlockNonce >= 0xffff0000)
genesis 3085 break;
genesis 3086 if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
genesis 3087 break;
genesis 3088 if (pindexPrev != pindexBest)
genesis 3089 break;
genesis 3090
genesis 3091
genesis 3092 pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
genesis 3093 nBlockTime = ByteReverse(pblock->nTime);
genesis 3094 }
genesis 3095 }
genesis 3096 }
genesis 3097
genesis 3098 void static ThreadBitcoinMiner(void* parg)
genesis 3099 {
genesis 3100 CWallet* pwallet = (CWallet*)parg;
genesis 3101 try
genesis 3102 {
genesis 3103 vnThreadsRunning[3]++;
genesis 3104 BitcoinMiner(pwallet);
genesis 3105 vnThreadsRunning[3]--;
genesis 3106 }
genesis 3107 catch (std::exception& e) {
genesis 3108 vnThreadsRunning[3]--;
genesis 3109 PrintException(&e, "ThreadBitcoinMiner()");
genesis 3110 } catch (...) {
genesis 3111 vnThreadsRunning[3]--;
genesis 3112 PrintException(NULL, "ThreadBitcoinMiner()");
genesis 3113 }
genesis 3114 UIThreadCall(boost::bind(CalledSetStatusBar, "", 0));
genesis 3115 nHPSTimerStart = 0;
genesis 3116 if (vnThreadsRunning[3] == 0)
genesis 3117 dHashesPerSec = 0;
genesis 3118 printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
genesis 3119 }
genesis 3120
genesis 3121
genesis 3122 void GenerateBitcoins(bool fGenerate, CWallet* pwallet)
genesis 3123 {
genesis 3124 if (fGenerateBitcoins != fGenerate)
genesis 3125 {
genesis 3126 fGenerateBitcoins = fGenerate;
genesis 3127 WriteSetting("fGenerateBitcoins", fGenerateBitcoins);
genesis 3128 MainFrameRepaint();
genesis 3129 }
genesis 3130 if (fGenerateBitcoins)
genesis 3131 {
genesis 3132 int nProcessors = boost::thread::hardware_concurrency();
genesis 3133 printf("%d processors\n", nProcessors);
genesis 3134 if (nProcessors < 1)
genesis 3135 nProcessors = 1;
genesis 3136 if (fLimitProcessors && nProcessors > nLimitProcessors)
genesis 3137 nProcessors = nLimitProcessors;
genesis 3138 int nAddThreads = nProcessors - vnThreadsRunning[3];
genesis 3139 printf("Starting %d BitcoinMiner threads\n", nAddThreads);
genesis 3140 for (int i = 0; i < nAddThreads; i++)
genesis 3141 {
genesis 3142 if (!CreateThread(ThreadBitcoinMiner, pwallet))
genesis 3143 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
genesis 3144 Sleep(10);
genesis 3145 }
genesis 3146 }
genesis 3147 }