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