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