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