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