- 02CCC72E42939509FC180861DB7FFEC50563A84869F35671FCF720090F9782674EDCC89C4174175691566FAC7277F1EBE0F50253D1E4A995EB960F5B43CCE2A3
+ B4775D56FD901D7AF16136590BE4645F57631004C4E0EC35332374EEDC78D8574D6A2162D7BBA121843F710111209336ECD6553AF4B576BAD81B3639D2634AD5
bitcoin/src/main.cpp
(213 . 7)(213 . 7)
366 {
367 vMerkleBranch.clear();
368 nIndex = -1;
369 printf("ERROR: SetMerkleBranch() : couldn't find tx in block\n");
370 printf(SERR SBLK "couldn't set merkle branch, tx not included in a block\n");
371 return 0;
372 }
373
(242 . 24)(242 . 29)
375 {
376 // Basic checks that don't depend on any context
377 if (vin.empty())
378 return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
379 return DoS(10, error(SMEM "tx %s validation failed, no inputs",
380 GetHash().ToString().c_str()));
381 if (vout.empty())
382 return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
383 return DoS(10, error(SMEM "tx %s validation failed, no ouputs",
384 GetHash().ToString().c_str()));
385 // Size limits
386 if (::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
387 return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
388
389 return DoS(100, error(SMEM "tx %s validation failed, size limits failed",
390 GetHash().ToString().c_str()));
391 // Check for negative or overflow output values
392 int64 nValueOut = 0;
393 BOOST_FOREACH(const CTxOut& txout, vout)
394 {
395 if (txout.nValue < 0)
396 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative"));
397 return DoS(100, error(SMEM "tx %s validation failed, output amount is negative",
398 GetHash().ToString().c_str()));
399 if (txout.nValue > MAX_MONEY)
400 return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high"));
401 return DoS(100, error(SMEM "tx %s validation failed, output amount out of range",
402 GetHash().ToString().c_str()));
403 nValueOut += txout.nValue;
404 if (!MoneyRange(nValueOut))
405 return DoS(100, error("CTransaction::CheckTransaction() : txout total out of range"));
406 return DoS(100, error(SMEM "tx %s validation failed, total output amount out of range",
407 GetHash().ToString().c_str()));
408 }
409
410 // Check for duplicate inputs
(267 . 20)(272 . 23)
412 BOOST_FOREACH(const CTxIn& txin, vin)
413 {
414 if (vInOutPoints.count(txin.prevout))
415 return false;
416 return error(SMEM "tx %s validation failed, duplicate input found",
417 GetHash().ToString().c_str());
418 vInOutPoints.insert(txin.prevout);
419 }
420
421 if (IsCoinBase())
422 {
423 if (vin[0].scriptSig.size() < 2 || vin[0].scriptSig.size() > 100)
424 return DoS(100, error("CTransaction::CheckTransaction() : coinbase script size"));
425 return DoS(100, error(SMEM "tx %s validation failed, coinbase script size out of range",
426 GetHash().ToString().c_str()));
427 }
428 else
429 {
430 BOOST_FOREACH(const CTxIn& txin, vin)
431 if (txin.prevout.IsNull())
432 return DoS(10, error("CTransaction::CheckTransaction() : prevout is null"));
433 return DoS(10, error(SMEM "tx %s validation failed, input specifies no previous output",
434 GetHash().ToString().c_str()));
435 }
436
437 return true;
(292 . 15)(300 . 17)
439 *pfMissingInputs = false;
440
441 if (!CheckTransaction())
442 return error("AcceptToMemoryPool() : CheckTransaction failed");
443 return error(SMEM "tx %s rejected", GetHash().ToString().c_str());
444
445 // Coinbase is only valid in a block, not as a loose transaction
446 if (IsCoinBase())
447 return DoS(100, error("AcceptToMemoryPool() : coinbase as individual tx"));
448 return DoS(100, error(SMEM "tx %s rejected, coinbase individual tx",
449 GetHash().ToString().c_str()));
450
451 // To help v0.1.5 clients who would see it as a negative number
452 if ((int64)nLockTime > INT_MAX)
453 return error("AcceptToMemoryPool() : not accepting nLockTime beyond 2038 yet");
454 return error(SMEM "tx %s rejected, locktime out of range",
455 GetHash().ToString().c_str());
456
457 // Safety limits
458 unsigned int nSize = ::GetSerializeSize(*this, SER_NETWORK);
(309 . 11)(319 . 13)
460 // 34 bytes because a TxOut is:
461 // 20-byte address + 8 byte bitcoin amount + 5 bytes of ops + 1 byte script length
462 if (GetSigOpCount() > nSize / 34 || nSize < 100)
463 return error("AcceptToMemoryPool() : transaction with out-of-bounds SigOpCount");
464 return error(SMEM "tx %s rejected, sigop count out of range",
465 GetHash().ToString().c_str());
466
467 // Rather not work on nonstandard transactions
468 if (!IsStandard())
469 return error("AcceptToMemoryPool() : nonstandard transaction type");
470 return error(SMEM "tx %s rejected, non-standard tx",
471 GetHash().ToString().c_str());
472
473 // Do we already have it?
474 uint256 hash = GetHash();
(361 . 13)(373 . 13)
476 if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
477 {
478 if (fInvalid)
479 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
480 return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
481 return error(SMEM "tx %s rejected, invalid input", hash.ToString().c_str());
482 return error(SMEM "tx %s rejected, input not found", hash.ToString().c_str());
483 }
484
485 // Don't accept it if it can't get into a block
486 if (nFees < GetMinFee(1000, true, true))
487 return error("AcceptToMemoryPool() : not enough fees");
488 return error(SMEM "tx %s rejected, not enough fees", hash.ToString().c_str());
489
490 // Continuously rate-limit free transactions
491 // This mitigates 'penny-flooding' -- sending thousands of free transactions just to
(387 . 9)(399 . 10)
493 // -limitfreerelay unit is thousand-bytes-per-minute
494 // At default rate it would take over a month to fill 1GB
495 if (dFreeCount > GetArg("-limitfreerelay", 15)*10*1000 && !IsFromMe(*this))
496 return error("AcceptToMemoryPool() : free transaction rejected by rate limiter");
497 return error(SMEM "tx %s rejected, free tx",
498 hash.ToString().c_str());
499 if (fDebug)
500 printf("Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize);
501 printf(SINF SMEM "updated free tx rate limit from %g to %g\n", dFreeCount, dFreeCount+nSize);
502 dFreeCount += nSize;
503 }
504 }
(400 . 7)(413 . 8)
506 {
507 if (ptxOld)
508 {
509 printf("AcceptToMemoryPool() : replacing tx %s with new version\n", ptxOld->GetHash().ToString().c_str());
510 printf(SWAR SMEM "replacing tx %s with new tx %s\n", ptxOld->GetHash().ToString().c_str(),
511 hash.ToString().c_str());
512 ptxOld->RemoveFromMemoryPool();
513 }
514 AddToMemoryPoolUnchecked();
(411 . 7)(425 . 7)
516 if (ptxOld)
517 EraseFromWallets(ptxOld->GetHash());
518
519 printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
520 printf(SINF SMEM "accepted tx %s\n", hash.ToString().c_str());
521 return true;
522 }
523
(576 . 7)(590 . 7)
525 if (!ReadFromDisk(pindex->nFile, pindex->nBlockPos, fReadTransactions))
526 return false;
527 if (GetHash() != pindex->GetBlockHash())
528 return error("CBlock::ReadFromDisk() : GetHash() doesn't match index");
529 return error(SBLK "block %s doesn't match index", GetHash().ToString().c_str());
530 return true;
531 }
532
(636 . 7)(650 . 7)
534
535 // Limit adjustment step
536 int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
537 printf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
538 printf(SINF SBLK "actual timestamp before bounds is %"PRI64d"\n", nActualTimespan);
539 if (nActualTimespan < nTargetTimespan/4)
540 nActualTimespan = nTargetTimespan/4;
541 if (nActualTimespan > nTargetTimespan*4)
(652 . 10)(666 . 11)
543 bnNew = bnProofOfWorkLimit;
544
545 /// debug print
546 printf("GetNextWorkRequired RETARGET\n");
547 printf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
548 printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
549 printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
550 printf(SINF SBLK "retargetting\n");
551 printf(SINF SBLK "target timestamp is %"PRI64d" and actual timespan is %"PRI64d"\n", nTargetTimespan, nActualTimespan);
552 printf(SINF SBLK "before: %08x %s\n", pindexLast->nBits,
553 CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
554 printf(SINF SBLK "after: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
555
556 return bnNew.GetCompact();
557 }
(667 . 11)(682 . 11)
559
560 // Check range
561 if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
562 return error("CheckProofOfWork() : nBits below minimum work");
563 return error(SBLK "pow %s work below minimum (%u)", hash.ToString().c_str(), nBits);
564
565 // Check proof of work matches claimed amount
566 if (hash > bnTarget.getuint256())
567 return error("CheckProofOfWork() : hash doesn't match nBits");
568 return error(SBLK "pow %s hash doesn't match work (%u)", hash.ToString().c_str(), nBits);
569
570 return true;
571 }
(705 . 10)(720 . 13)
573 CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
574 MainFrameRepaint();
575 }
576 printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
577 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
578 printf(SERR SBLK "invalid chain tip %s at height %d with work %s\n",
579 pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight,
580 pindexNew->bnChainWork.ToString().c_str());
581 printf(SINF SBLK "best chain tip %s at height %d with work %s\n",
582 hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
583 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
584 printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
585 printf(SWAR SBLK "displayed transactions may not be correct, there's chain discrepancy between this and other nodes\n");
586 }
587
588
(733 . 17)(751 . 19)
590 // Get prev txindex from disk
591 CTxIndex txindex;
592 if (!txdb.ReadTxIndex(prevout.hash, txindex))
593 return error("DisconnectInputs() : ReadTxIndex failed");
594 return error(SMEM "input referenced non-existing output %d from tx %s",
595 prevout.n, prevout.hash.ToString().c_str());
596
597 if (prevout.n >= txindex.vSpent.size())
598 return error("DisconnectInputs() : prevout.n out of range");
599 return error(SMEM "input referenced out of range output %d from tx %s ",
600 prevout.n, prevout.hash.ToString().c_str());
601
602 // Mark outpoint as not spent
603 txindex.vSpent[prevout.n].SetNull();
604
605 // Write back
606 if (!txdb.UpdateTxIndex(prevout.hash, txindex))
607 return error("DisconnectInputs() : UpdateTxIndex failed");
608 return error(SMEM "tx index can't be updated");
609 }
610 }
611
(792 . 7)(812 . 8)
613 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
614 }
615 if (!fFound && (fBlock || fMiner))
616 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
617 return fMiner ? false : error(SMEM "tx %s not found in index",
618 prevout.hash.ToString().c_str());
619
620 // Read txPrev
621 CTransaction txPrev;
(802 . 7)(823 . 8)
623 CRITICAL_BLOCK(cs_mapTransactions)
624 {
625 if (!mapTransactions.count(prevout.hash))
626 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
627 return error(SMEM "tx %s not found in memory pool",
628 prevout.hash.ToString().c_str());
629 txPrev = mapTransactions[prevout.hash];
630 }
631 if (!fFound)
(812 . 7)(834 . 8)
633 {
634 // Get prev tx from disk
635 if (!txPrev.ReadFromDisk(txindex.pos))
636 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
637 return error(SMEM "tx %s not found in disk",
638 prevout.hash.ToString().c_str());
639 }
640
641 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
(820 . 14)(843 . 16)
643 // Revisit this if/when transaction replacement is implemented and allows
644 // adding inputs:
645 fInvalid = true;
646 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
647 return DoS(100, error(SMEM "output %d from tx %s is out of range",
648 prevout.n, prevout.hash.ToString().c_str()));
649 }
650
651 // If prev is coinbase, check that it's matured
652 if (txPrev.IsCoinBase())
653 for (CBlockIndex* pindex = pindexBlock; pindex && pindexBlock->nHeight - pindex->nHeight < COINBASE_MATURITY; pindex = pindex->pprev)
654 if (pindex->nBlockPos == txindex.pos.nBlockPos && pindex->nFile == txindex.pos.nFile)
655 return error("ConnectInputs() : tried to spend coinbase at depth %d", pindexBlock->nHeight - pindex->nHeight);
656 return error(SMEM "tx %s tried to spend coinbase at depth %d",
657 GetHash().ToString().c_str(), pindexBlock->nHeight - pindex->nHeight);
658
659 // Skip ECDSA signature verification when connecting blocks (fBlock=true)
660 // before the last blockchain checkpoint. This is safe because block merkle hashes are
(835 . 18)(860 . 21)
662 if (fVerifyAll || (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate()))))
663 // Verify signature
664 if (!VerifySignature(txPrev, *this, i))
665 return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
666 return DoS(100,error(SMEM "tx %s signature verification failed",
667 GetHash().ToString().c_str()));
668
669 // Check for conflicts (double-spend)
670 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
671 // for an attacker to attempt to split the network.
672 if (!txindex.vSpent[prevout.n].IsNull())
673 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
674 return fMiner ? false : error(SMEM "output %d from tx %s already spent",
675 prevout.n, prevout.hash.ToString().c_str());
676
677 // Check for negative or overflow input values
678 nValueIn += txPrev.vout[prevout.n].nValue;
679 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
680 return DoS(100, error("ConnectInputs() : txin values out of range"));
681 return DoS(100, error(SMEM "output %d from tx %s contains out of range amount",
682 prevout.n, prevout.hash.ToString().c_str()));
683
684 // Mark outpoints as spent
685 txindex.vSpent[prevout.n] = posThisTx;
(858 . 18)(886 . 20)
687 }
688 }
689
690 if (nValueIn < GetValueOut())
691 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
692 int64 nValueOut = GetValueOut();
693 if (nValueIn < nValueOut)
694 return DoS(100, error(SMEM "tx %s output amount is greater than input amount",
695 GetHash().ToString().c_str()));
696
697 // Tally transaction fees
698 int64 nTxFee = nValueIn - GetValueOut();
699 int64 nTxFee = nValueIn - nValueOut;
700 if (nTxFee < 0)
701 return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
702 return DoS(100, error(SMEM "tx %s fee is negative", GetHash().ToString().c_str()));
703 if (nTxFee < nMinFee)
704 return false;
705 nFees += nTxFee;
706 if (!MoneyRange(nFees))
707 return DoS(100, error("ConnectInputs() : nFees out of range"));
708 return DoS(100, error(SMEM "tx %s fee is out of range", GetHash().ToString().c_str()));
709 }
710
711 if (fBlock)
(909 . 7)(939 . 8)
713
714 // Verify signature
715 if (!VerifySignature(txPrev, *this, i))
716 return error("ConnectInputs() : VerifySignature failed");
717 return error(SMEM "tx %s signature verification against tx %s failed",
718 GetHash().ToString().c_str(), txPrev.GetHash().ToString().c_str());
719
720 ///// this is redundant with the mapNextTx stuff, not sure which I want to get rid of
721 ///// this has to go away now that posNext is gone
(923 . 7)(954 . 8)
723 nValueIn += txPrev.vout[prevout.n].nValue;
724
725 if (!MoneyRange(txPrev.vout[prevout.n].nValue) || !MoneyRange(nValueIn))
726 return error("ClientConnectInputs() : txin values out of range");
727 return error(SMEM "tx %s input amounts are out of range",
728 GetHash().ToString().c_str());
729 }
730 if (GetValueOut() > nValueIn)
731 return false;
(949 . 7)(981 . 7)
733 CDiskBlockIndex blockindexPrev(pindex->pprev);
734 blockindexPrev.hashNext = 0;
735 if (!txdb.WriteBlockIndex(blockindexPrev))
736 return error("DisconnectBlock() : WriteBlockIndex failed");
737 return error(SBLK "writing to block index failed while disconnecting block");
738 }
739
740 return true;
(998 . 7)(1030 . 7)
742 for (map<uint256, CTxIndex>::iterator mi = mapQueuedChanges.begin(); mi != mapQueuedChanges.end(); ++mi)
743 {
744 if (!txdb.UpdateTxIndex((*mi).first, (*mi).second))
745 return error("ConnectBlock() : UpdateTxIndex failed");
746 return error(SMEM "tx index update failed");
747 }
748
749 if (vtx[0].GetValueOut() > GetBlockValue(pindex->nHeight, nFees))
(1011 . 7)(1043 . 7)
751 CDiskBlockIndex blockindexPrev(pindex->pprev);
752 blockindexPrev.hashNext = pindex->GetBlockHash();
753 if (!txdb.WriteBlockIndex(blockindexPrev))
754 return error("ConnectBlock() : WriteBlockIndex failed");
755 return error(SBLK "writing to block index failed while connecting block");
756 }
757
758 // Watch for transactions paying to me
(1023 . 7)(1055 . 7)
760
761 bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
762 {
763 printf("REORGANIZE\n");
764 printf(SINF SBLK "reorganizing block index\n");
765
766 // Find the fork
767 CBlockIndex* pfork = pindexBest;
(1032 . 11)(1064 . 11)
769 {
770 while (plonger->nHeight > pfork->nHeight)
771 if (!(plonger = plonger->pprev))
772 return error("Reorganize() : plonger->pprev is null");
773 return error(SBLK "invalid pointer to previous block from longest chain tip");
774 if (pfork == plonger)
775 break;
776 if (!(pfork = pfork->pprev))
777 return error("Reorganize() : pfork->pprev is null");
778 return error(SBLK "invalid pointer to previous block from new longest chain tip");
779 }
780
781 // List of what to disconnect
(1056 . 9)(1088 . 9)
783 {
784 CBlock block;
785 if (!block.ReadFromDisk(pindex))
786 return error("Reorganize() : ReadFromDisk for disconnect failed");
787 return error(SBLK "block loading from disk failed while trying to disconnect block");
788 if (!block.DisconnectBlock(txdb, pindex))
789 return error("Reorganize() : DisconnectBlock failed");
790 return error(SBLK "block index reorganization failed while trying to disconnect block");
791
792 // Queue memory transactions to resurrect
793 BOOST_FOREACH(const CTransaction& tx, block.vtx)
(1073 . 12)(1105 . 12)
795 CBlockIndex* pindex = vConnect[i];
796 CBlock block;
797 if (!block.ReadFromDisk(pindex))
798 return error("Reorganize() : ReadFromDisk for connect failed");
799 return error(SBLK "block loading from disk failed while trying to connect block");
800 if (!block.ConnectBlock(txdb, pindex))
801 {
802 // Invalid block
803 txdb.TxnAbort();
804 return error("Reorganize() : ConnectBlock failed");
805 return error(SBLK "block index reorganization failed while trying to connect block");
806 }
807
808 // Queue memory transactions to delete
(1086 . 11)(1118 . 11)
810 vDelete.push_back(tx);
811 }
812 if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash()))
813 return error("Reorganize() : WriteHashBestChain failed");
814 return error(SBLK "block writing to index failed while trying to save best chain");
815
816 // Make sure it's successfully written to disk before changing memory structure
817 if (!txdb.TxnCommit())
818 return error("Reorganize() : TxnCommit failed");
819 return error(SMEM "tx index commitment failed while reorganizing block index");
820
821 // Disconnect shorter branch
822 BOOST_FOREACH(CBlockIndex* pindex, vDisconnect)
(1123 . 7)(1155 . 7)
824 {
825 txdb.WriteHashBestChain(hash);
826 if (!txdb.TxnCommit())
827 return error("SetBestChain() : TxnCommit failed");
828 return error(SMEM "tx index commitment failed while setting best chain");
829 pindexGenesisBlock = pindexNew;
830 }
831 else if (hashPrevBlock == hashBestChain)
(1133 . 10)(1165 . 10)
833 {
834 txdb.TxnAbort();
835 InvalidChainFound(pindexNew);
836 return error("SetBestChain() : ConnectBlock failed");
837 return error(SBLK "block connecting failed while setting best chain");
838 }
839 if (!txdb.TxnCommit())
840 return error("SetBestChain() : TxnCommit failed");
841 return error(SMEM "tx index commitment failed while setting best chain");
842
843 // Add to current best branch
844 pindexNew->pprev->pnext = pindexNew;
(1152 . 7)(1184 . 7)
846 {
847 txdb.TxnAbort();
848 InvalidChainFound(pindexNew);
849 return error("SetBestChain() : Reorganize failed");
850 return error(SBLK "block reorganization failed while setting best chain");
851 }
852 }
853
(1170 . 7)(1202 . 7)
855 bnBestChainWork = pindexNew->bnChainWork;
856 nTimeBestReceived = GetTime();
857 nTransactionsUpdated++;
858 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
859 printf(SINF SBLK "chain tip %s at height %d\n", hashBestChain.ToString().c_str(), nBestHeight);
860
861 return true;
862 }
(1181 . 12)(1213 . 12)
864 // Check for duplicate
865 uint256 hash = GetHash();
866 if (mapBlockIndex.count(hash))
867 return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
868 return error(SBLK "block %s already exists in block index", hash.ToString().c_str());
869
870 // Construct new block index object
871 CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
872 if (!pindexNew)
873 return error("AddToBlockIndex() : new CBlockIndex failed");
874 return error(SBLK "block index initialization failed");
875 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
876 pindexNew->phashBlock = &((*mi).first);
877 map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
(1232 . 35)(1264 . 36)
879
880 // Size limits
881 if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK) > MAX_BLOCK_SIZE)
882 return DoS(100, error("CheckBlock() : size limits failed"));
883 return DoS(100, error(SBLK "block %s size is out of range", GetHash().ToString().c_str()));
884
885 // Check proof of work matches claimed amount
886 if (!CheckProofOfWork(GetHash(), nBits))
887 return DoS(50, error("CheckBlock() : proof of work failed"));
888 uint256 hash = GetHash();
889 if (!CheckProofOfWork(hash, nBits))
890 return DoS(50, error(SBLK "block %s proof of work is invalid", hash.ToString().c_str()));
891
892 // Check timestamp
893 if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
894 return error("CheckBlock() : block timestamp too far in the future");
895 return error(SBLK "block %s timestamp is too far in the future", hash.ToString().c_str());
896
897 // First transaction must be coinbase, the rest must not be
898 if (vtx.empty() || !vtx[0].IsCoinBase())
899 return DoS(100, error("CheckBlock() : first tx is not coinbase"));
900 return DoS(100, error(SBLK "block %s first tx is not a coinbase tx", hash.ToString().c_str()));
901 for (int i = 1; i < vtx.size(); i++)
902 if (vtx[i].IsCoinBase())
903 return DoS(100, error("CheckBlock() : more than one coinbase"));
904 return DoS(100, error(SBLK "block %s has more than one coinbase tx", hash.ToString().c_str()));
905
906 // Check transactions
907 BOOST_FOREACH(const CTransaction& tx, vtx)
908 if (!tx.CheckTransaction())
909 return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
910 return DoS(tx.nDoS, error(SBLK "block %s tx check failed", hash.ToString().c_str()));
911
912 // Check that it's not full of nonstandard transactions
913 if (GetSigOpCount() > MAX_BLOCK_SIGOPS)
914 return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));
915 return DoS(100, error(SBLK "block %s sigopt count out of range", hash.ToString().c_str()));
916
917 // Check merkleroot
918 if (hashMerkleRoot != BuildMerkleTree())
919 return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));
920 return DoS(100, error(SBLK "block %s merkle root hash mistmatch", hash.ToString().c_str()));
921
922 return true;
923 }
(1270 . 41)(1303 . 42)
925 // Check for duplicate
926 uint256 hash = GetHash();
927 if (mapBlockIndex.count(hash))
928 return error("AcceptBlock() : block already in mapBlockIndex");
929 return error(SBLK "block %s already in block index", hash.ToString().c_str());
930
931 // Get prev block index
932 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
933 if (mi == mapBlockIndex.end())
934 return DoS(10, error("AcceptBlock() : prev block not found"));
935 return DoS(10, error(SBLK "block %s not found in index",
936 hashPrevBlock.ToString().c_str()));
937 CBlockIndex* pindexPrev = (*mi).second;
938 int nHeight = pindexPrev->nHeight+1;
939
940 // Check proof of work
941 if (nBits != GetNextWorkRequired(pindexPrev, this))
942 return DoS(100, error("AcceptBlock() : incorrect proof of work"));
943 return DoS(100, error(SBLK "block %s proof of work is invalid", hash.ToString().c_str()));
944
945 // Check timestamp against prev
946 if (GetBlockTime() <= pindexPrev->GetMedianTimePast())
947 return error("AcceptBlock() : block's timestamp is too early");
948 return error(SBLK "block %s timestamp is too early", hash.ToString().c_str());
949
950 // Check that all transactions are finalized
951 BOOST_FOREACH(const CTransaction& tx, vtx)
952 if (!tx.IsFinal(nHeight, GetBlockTime()))
953 return DoS(10, error("AcceptBlock() : contains a non-final transaction"));
954 return DoS(10, error(SBLK "block %s contains a non-final tx", hash.ToString().c_str()));
955
956 // Check that the block chain matches the known block chain up to a checkpoint
957 if (!Checkpoints::CheckBlock(nHeight, hash))
958 return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight));
959 return DoS(100, error(SBLK "block %s rejected by checkpoint locking at height %d", hash.ToString().c_str(), nHeight));
960
961 // Write block to history file
962 if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))
963 return error("AcceptBlock() : out of disk space");
964 return error(SBLK "block %s writing to disk failure due out of space", hash.ToString().c_str());
965 unsigned int nFile = -1;
966 unsigned int nBlockPos = 0;
967 if (!WriteToDisk(nFile, nBlockPos))
968 return error("AcceptBlock() : WriteToDisk failed");
969 return error(SBLK "block %s writing to disk failure", hash.ToString().c_str());
970 if (!AddToBlockIndex(nFile, nBlockPos))
971 return error("AcceptBlock() : AddToBlockIndex failed");
972 return error(SBLK "block %s write to block index failure", hash.ToString().c_str());
973
974 // Relay inventory, but don't relay old inventory during initial block download
975 if (hashBestChain == hash)
(1321 . 11)(1355 . 12)
977 // Check for duplicate
978 uint256 hash = pblock->GetHash();
979 if (mapBlockIndex.count(hash))
980 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
981 return error(SBLK "block %s already in index at height %d",
982 hash.ToString().c_str(), mapBlockIndex[hash]->nHeight);
983
984 // Preliminary checks
985 if (!pblock->CheckBlock())
986 return error("ProcessBlock() : CheckBlock FAILED");
987 return error(SBLK "block %s check failed", hash.ToString().c_str());
988
989 CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
990 if (pcheckpoint && pblock->hashPrevBlock != hashBestChain)
(1336 . 7)(1371 . 8)
992 {
993 if (pfrom)
994 pfrom->Misbehaving(100);
995 return error("ProcessBlock() : block with timestamp before last checkpoint");
996 return error(SBLK "block %s timestamp is lower than last checkpint",
997 hash.ToString().c_str());
998 }
999 CBigNum bnNewBlock;
1000 bnNewBlock.SetCompact(pblock->nBits);
(1346 . 14)(1382 . 16)
1002 {
1003 if (pfrom)
1004 pfrom->Misbehaving(100);
1005 return error("ProcessBlock() : block with too little proof-of-work");
1006 return error(SBLK "block %s proof-of-work is insufficient",
1007 hash.ToString().c_str());
1008 }
1009 }
1010
1011 // If don't already have its previous block, throw it out!
1012 if (!mapBlockIndex.count(pblock->hashPrevBlock))
1013 {
1014 printf("ProcessBlock: BASTARD BLOCK, prev=%s, DISCARDED\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
1015 printf(SWAR SBLK "found bastard block %s referencing previous block %s, will now be discarded\n",
1016 hash.ToString().c_str(), pblock->hashPrevBlock.ToString().c_str());
1017
1018 // Ask this guy to fill in what we're missing
1019 if (pfrom)
(1364 . 9)(1402 . 9)
1021
1022 // Store to disk
1023 if (!pblock->AcceptBlock())
1024 return error("ProcessBlock() : AcceptBlock FAILED");
1025 return error(SBLK "block %s rejected", hash.ToString().c_str());
1026
1027 printf("ProcessBlock: ACCEPTED\n");
1028 printf(SINF SBLK "block %s accepted\n", hash.ToString().c_str());
1029 return true;
1030 }
1031
(1385 . 10)(1423 . 7)
1033 if (nFreeBytesAvailable < (uint64)15000000 + nAdditionalBytes)
1034 {
1035 fShutdown = true;
1036 string strMessage = _("Warning: Disk space is low ");
1037 strMiscWarning = strMessage;
1038 printf("*** %s\n", strMessage.c_str());
1039 ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION);
1040 printf(SWAR SPRC "disk space low\n");
1041 CreateThread(Shutdown, NULL);
1042 return false;
1043 }
(1479 . 9)(1514 . 9)
1045 block.nNonce = 2083236893;
1046
1047 //// debug print
1048 printf("%s\n", block.GetHash().ToString().c_str());
1049 printf("%s\n", hashGenesisBlock.ToString().c_str());
1050 printf("%s\n", block.hashMerkleRoot.ToString().c_str());
1051 printf(SINF SBLK "loaded genesis block %s\n", block.GetHash().ToString().c_str());
1052 printf(SINF SBLK "block hash should be %s\n", hashGenesisBlock.ToString().c_str());
1053 printf(SINF SBLK "merkle root is %s\n", block.hashMerkleRoot.ToString().c_str());
1054 assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
1055 block.print();
1056 assert(block.GetHash() == hashGenesisBlock);
(1490 . 9)(1525 . 9)
1058 unsigned int nFile;
1059 unsigned int nBlockPos;
1060 if (!block.WriteToDisk(nFile, nBlockPos))
1061 return error("LoadBlockIndex() : writing genesis block to disk failed");
1062 return error(SBLK "genesis block writing to disk failure");
1063 if (!block.AddToBlockIndex(nFile, nBlockPos))
1064 return error("LoadBlockIndex() : genesis block not accepted");
1065 return error(SBLK "genesis block rejected");
1066 }
1067
1068 return true;
(1549 . 7)(1584 . 7)
1070 pindex->nHeight,
1071 pindex->nFile,
1072 pindex->nBlockPos,
1073 block.GetHash().ToString().substr(0,20).c_str(),
1074 block.GetHash().ToString().c_str(),
1075 DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
1076 block.vtx.size());
1077
(1641 . 12)(1676 . 11)
1079 static map<unsigned int, vector<unsigned char> > mapReuseKey;
1080 RandAddSeedPerfmon();
1081 if (fDebug) {
1082 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
1083 printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
1084 printf(SINF SNET "received %s (%d bytes)\n", strCommand.c_str(), vRecv.size());
1085 }
1086 if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
1087 {
1088 printf("dropmessagestest DROPPING RECV MESSAGE\n");
1089 printf(SWAR SNET "dropping test message\n");
1090 return true;
1091 }
1092
(1683 . 7)(1717 . 7)
1094 // Disconnect if we connected to ourself
1095 if (nNonce == nLocalHostNonce && nNonce > 1)
1096 {
1097 printf("connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
1098 printf(SINF SNET "connected to self at %s, disconnecting\n", pfrom->addr.ToString().c_str());
1099 pfrom->fDisconnect = true;
1100 return true;
1101 }
(1733 . 7)(1767 . 7)
1103
1104 pfrom->fSuccessfullyConnected = true;
1105
1106 printf("version message: version %d, blocks=%d\n", pfrom->nVersion, pfrom->nStartingHeight);
1107 printf(SINF SNET "received version %d, height %d\n", pfrom->nVersion, pfrom->nStartingHeight);
1108
1109 cPeerBlockCounts.input(pfrom->nStartingHeight);
1110 }
(1766 . 7)(1800 . 7)
1112 if (vAddr.size() > 1000)
1113 {
1114 pfrom->Misbehaving(20);
1115 return error("message addr size() = %d", vAddr.size());
1116 return error(SNET "addr message size out of range. (%d)", vAddr.size());
1117 }
1118
1119 // Store the new addresses
(1827 . 7)(1861 . 7)
1121 if (vInv.size() > 50000)
1122 {
1123 pfrom->Misbehaving(20);
1124 return error("message inv size() = %d", vInv.size());
1125 return error(SNET "inv message size out of range. (%d)", vInv.size());
1126 }
1127
1128 CTxDB txdb("r");
(1839 . 7)(1873 . 8)
1130
1131 bool fAlreadyHave = AlreadyHave(txdb, inv);
1132 if (fDebug)
1133 printf(" got inventory: %s %s\n", inv.ToString().c_str(), fAlreadyHave ? "have" : "new");
1134 printf(SINF SNET "received%s: %s\n",
1135 fAlreadyHave ? " already seen" : " new", inv.ToString().c_str());
1136
1137 if (!fAlreadyHave)
1138 pfrom->AskFor(inv);
(1857 . 14)(1892 . 14)
1140 if (vInv.size() > 50000)
1141 {
1142 pfrom->Misbehaving(20);
1143 return error("message getdata size() = %d", vInv.size());
1144 return error(SNET "getdata message size out of range. (%d)", vInv.size());
1145 }
1146
1147 BOOST_FOREACH(const CInv& inv, vInv)
1148 {
1149 if (fShutdown)
1150 return true;
1151 printf("received getdata for: %s\n", inv.ToString().c_str());
1152 printf(SINF SNET "received getdata %s\n", inv.ToString().c_str());
1153
1154 if (inv.type == MSG_BLOCK)
1155 {
(1902 . 7)(1937 . 8)
1157 else
1158 {
1159 pfrom->Misbehaving(100);
1160 return error("BANNED peer issuing unknown inv type.");
1161 return error(SNET "peer %s banned for issuing unknown inv message type",
1162 pfrom->addr.ToString().c_str());
1163 }
1164
1165 // Track requests for our stuff
(1925 . 12)(1961 . 14)
1167 pindex = pindex->pnext;
1168 int nLimit = 500 + locator.GetDistanceBack();
1169 unsigned int nBytes = 0;
1170 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
1171 printf(SINF SNET "received getblocks height %d, block %s, limit %d\n",
1172 (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
1173 for (; pindex; pindex = pindex->pnext)
1174 {
1175 if (pindex->GetBlockHash() == hashStop)
1176 {
1177 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
1178 printf(SINF SNET "getblocks response stopping on block %s at height %d. (%u bytes)\n",
1179 pindex->GetBlockHash().ToString().c_str(), pindex->nHeight, nBytes);
1180 break;
1181 }
1182 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
(1941 . 7)(1979 . 8)
1184 {
1185 // When this block is requested, we'll send an inv that'll make them
1186 // getblocks the next batch of inventory.
1187 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
1188 printf(SINF SNET "getblocks response stopping on block %s at height %d. (%u bytes)\n",
1189 pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), nBytes);
1190 pfrom->hashContinue = pindex->GetBlockHash();
1191 break;
1192 }
(1974 . 7)(2013 . 8)
1194
1195 vector<CBlock> vHeaders;
1196 int nLimit = 2000 + locator.GetDistanceBack();
1197 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
1198 printf(SINF SNET "received getheaders height %d, block %s, limit %d\n",
1199 (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
1200 for (; pindex; pindex = pindex->pnext)
1201 {
1202 vHeaders.push_back(pindex->GetBlockHeader());
(2005 . 7)(2045 . 7)
1204 }
1205 else if (fMissingInputs)
1206 {
1207 printf("REJECTED orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
1208 printf(SWAR SNET "tx %s rejected as orphan\n", inv.hash.ToString().c_str());
1209 }
1210 if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
1211 }
(2016 . 7)(2056 . 7)
1213 CBlock block;
1214 vRecv >> block;
1215
1216 printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
1217 printf(SINF SNET "received block %s\n", block.GetHash().ToString().c_str());
1218 // block.print();
1219
1220 CInv inv(MSG_BLOCK, block.GetHash());
(2108 . 7)(2148 . 8)
1222 {
1223 // He who comes to us with a turd, by the turd shall perish.
1224 pfrom->Misbehaving(100);
1225 return error("BANNED peer issuing heathen command.");
1226 return error(SNET "peer %s banned for issuing unknown message",
1227 pfrom->addr.ToString().c_str());
1228 }
1229
1230
(2147 . 13)(2188 . 13)
1232 {
1233 if (vRecv.size() > nHeaderSize)
1234 {
1235 printf("\n\nPROCESSMESSAGE MESSAGESTART NOT FOUND\n\n");
1236 printf(SWAR SNET "message start couldn't be found while processing message\n");
1237 vRecv.erase(vRecv.begin(), vRecv.end() - nHeaderSize);
1238 }
1239 break;
1240 }
1241 if (pstart - vRecv.begin() > 0)
1242 printf("\n\nPROCESSMESSAGE SKIPPED %d BYTES\n\n", pstart - vRecv.begin());
1243 printf(SWAR SNET "skipped %d bytes while processing message\n", pstart - vRecv.begin());
1244 vRecv.erase(vRecv.begin(), pstart);
1245
1246 // Read header
(2162 . 7)(2203 . 7)
1248 vRecv >> hdr;
1249 if (!hdr.IsValid())
1250 {
1251 printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str());
1252 printf(SERR SNET "errors found in message %s header while processing message\n", hdr.GetCommand().c_str());
1253 continue;
1254 }
1255 string strCommand = hdr.GetCommand();
(2171 . 7)(2212 . 7)
1257 unsigned int nMessageSize = hdr.nMessageSize;
1258 if (nMessageSize > MAX_SIZE)
1259 {
1260 printf("ProcessMessage(%s, %u bytes) : nMessageSize > MAX_SIZE\n", strCommand.c_str(), nMessageSize);
1261 printf(SERR SNET "message %s size out of range. (%u bytes)\n", strCommand.c_str(), nMessageSize);
1262 continue;
1263 }
1264 if (nMessageSize > vRecv.size())
(2189 . 8)(2230 . 9)
1266 memcpy(&nChecksum, &hash, sizeof(nChecksum));
1267 if (nChecksum != hdr.nChecksum)
1268 {
1269 printf("ProcessMessage(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
1270 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
1271 printf(SERR SNET "message %s checksum error while processing message"
1272 " (%u bytes, checksum %08x, header checksum %08x)\n",
1273 strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum);
1274 continue;
1275 }
1276 }
(2213 . 12)(2255 . 15)
1278 if (strstr(e.what(), "end of data"))
1279 {
1280 // Allow exceptions from underlength message on vRecv
1281 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());
1282 printf(SERR SNET "message %s caught exception '%s' while processing message,"
1283 " normally caused by a message being shorter than its stated length. (%u bytes)\n",
1284 strCommand.c_str(), e.what(), nMessageSize);
1285 }
1286 else if (strstr(e.what(), "size too large"))
1287 {
1288 // Allow exceptions from overlong size
1289 printf("ProcessMessage(%s, %u bytes) : Exception '%s' caught\n", strCommand.c_str(), nMessageSize, e.what());
1290 printf(SERR SNET "message %s caught exception '%s' while processing message. (%u bytes)\n",
1291 strCommand.c_str(), e.what(), nMessageSize);
1292 }
1293 else
1294 {
(2232 . 7)(2277 . 7)
1296 }
1297
1298 if (!fRet)
1299 printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize);
1300 printf(SWAR SNET "failed to process message %s. (%u bytes)\n", strCommand.c_str(), nMessageSize);
1301 }
1302
1303 vRecv.Compact();
(2403 . 7)(2448 . 7)
1305 const CInv& inv = (*pto->mapAskFor.begin()).second;
1306 if (!AlreadyHave(txdb, inv))
1307 {
1308 printf("sending getdata: %s\n", inv.ToString().c_str());
1309 printf(SINF SNET "sending getdata %s\n", inv.ToString().c_str());
1310 vGetData.push_back(inv);
1311 if (vGetData.size() >= 1000)
1312 {
(2595 . 7)(2640 . 8)
1314 dPriority += (double)nValueIn * nConf;
1315
1316 if (fDebug && GetBoolArg("-printpriority"))
1317 printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
1318 printf(SINF SMEM "priority: %-20.1f, tx inputs value: %-12I64d, confirmations: %-5d\n",
1319 dPriority, nValueIn, nConf);
1320 }
1321
1322 // Priority is sum(valuein * age) / txsize
(2608 . 10)(2654 . 9)
1324
1325 if (fDebug && GetBoolArg("-printpriority"))
1326 {
1327 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
1328 printf(SINF SMEM "tx %s priority is %-20.1f\n", tx.GetHash().ToString().c_str(), dPriority);
1329 if (porphan)
1330 porphan->print();
1331 printf("\n");
1332 }
1333 }
1334
(2750 . 17)(2795 . 15)
1336 return false;
1337
1338 //// debug print
1339 printf("BitcoinMiner:\n");
1340 printf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
1341 printf(SINF SMIN "miner found proof-of-work %s with target %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str());
1342 pblock->print();
1343 printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str());
1344 printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
1345 printf(SINF SMIN "miner generated %s bitcoin\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str());
1346
1347 // Found a solution
1348 CRITICAL_BLOCK(cs_main)
1349 {
1350 if (pblock->hashPrevBlock != hashBestChain)
1351 return error("BitcoinMiner : generated block is stale");
1352 return error(SMIN "miner generated a stale block %s", hash.ToString().c_str());
1353
1354 // Remove key from key pool
1355 reservekey.KeepKey();
(2771 . 7)(2814 . 7)
1357
1358 // Process this block the same as if we had received it from another node
1359 if (!ProcessBlock(NULL, pblock))
1360 return error("BitcoinMiner : ProcessBlock, block not accepted");
1361 return error(SMIN "miner rejected block %s", hash.ToString().c_str());
1362 }
1363
1364 return true;
(2781 . 7)(2824 . 7)
1366
1367 void static BitcoinMiner(CWallet *pwallet)
1368 {
1369 printf("BitcoinMiner started\n");
1370 printf(SINF SMIN "miner started\n");
1371 SetThreadPriority(THREAD_PRIORITY_LOWEST);
1372
1373 // Each thread has its own key and counter
(2815 . 7)(2858 . 7)
1375 return;
1376 IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
1377
1378 printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());
1379 printf(SINF SMIN "miner running with %d transactions in block\n", pblock->vtx.size());
1380
1381
1382 //
(2941 . 7)(2984 . 7)
1384 nHPSTimerStart = 0;
1385 if (vnThreadsRunning[3] == 0)
1386 dHashesPerSec = 0;
1387 printf("ThreadBitcoinMiner exiting, %d threads remaining\n", vnThreadsRunning[3]);
1388 printf(SINF SMIN "miner thread exiting, %d threads remaining\n", vnThreadsRunning[3]);
1389 }
1390
1391
(2956 . 17)(2999 . 17)
1393 if (fGenerateBitcoins)
1394 {
1395 int nProcessors = boost::thread::hardware_concurrency();
1396 printf("%d processors\n", nProcessors);
1397 printf(SINF SMIN "miner using %d processors\n", nProcessors);
1398 if (nProcessors < 1)
1399 nProcessors = 1;
1400 if (fLimitProcessors && nProcessors > nLimitProcessors)
1401 nProcessors = nLimitProcessors;
1402 int nAddThreads = nProcessors - vnThreadsRunning[3];
1403 printf("Starting %d BitcoinMiner threads\n", nAddThreads);
1404 printf(SINF SMIN "miner starting %d threads\n", nAddThreads);
1405 for (int i = 0; i < nAddThreads; i++)
1406 {
1407 if (!CreateThread(ThreadBitcoinMiner, pwallet))
1408 printf("Error: CreateThread(ThreadBitcoinMiner) failed\n");
1409 printf(SERR SMIN "miner can't create thread\n");
1410 Sleep(10);
1411 }
1412 }