Get rid of main.cpp
This commit is contained in:
parent
38db96811b
commit
6300009a6e
3 changed files with 336 additions and 40 deletions
327
src/bitcoinminer.cpp
Normal file
327
src/bitcoinminer.cpp
Normal file
|
@ -0,0 +1,327 @@
|
|||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2012 The Bitcoin developers
|
||||
// Copyright (c) 2011-2013 PPCoin developers
|
||||
// Copyright (c) 2013 Primecoin developers
|
||||
// Distributed under conditional MIT/X11 software license,
|
||||
// see the accompanying file COPYING
|
||||
|
||||
#include "prime.h"
|
||||
#include "json/json_spirit_value.h"
|
||||
//#include <boost/algorithm/string/replace.hpp>
|
||||
//#include <boost/filesystem.hpp>
|
||||
//#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
CBlockIndex* pindexBest = NULL;
|
||||
int64 nHPSTimerStart = 0;
|
||||
|
||||
void BitcoinMiner(CBlockProvider *block_provider, unsigned int thread_id)
|
||||
{
|
||||
printf("PrimecoinMiner started\n");
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
RenameThread("primecoin-miner");
|
||||
|
||||
// Each thread has its own kcd ey and counter
|
||||
unsigned int nExtraNonce = 0; //^
|
||||
|
||||
unsigned int nPrimorialMultiplier = nPrimorialHashFactor;
|
||||
double dTimeExpected = 0; // time expected to prime chain (micro-second)
|
||||
int64 nSieveGenTime = 0; // how many milliseconds sieve generation took
|
||||
bool fIncrementPrimorial = true; // increase or decrease primorial factor
|
||||
|
||||
CBlock *pblock = NULL;
|
||||
uint256 old_hash;
|
||||
unsigned int old_nonce = 0;
|
||||
|
||||
try { loop {
|
||||
//
|
||||
// Create new block
|
||||
//
|
||||
CBlockIndex* pindexPrev = pindexBest;
|
||||
|
||||
auto_ptr<CBlockTemplate> pblocktemplate;
|
||||
if ((pblock = block_provider->getBlock(thread_id, pblock == NULL ? 0 : pblock->nTime)) == NULL) { //server not reachable?
|
||||
MilliSleep(20000);
|
||||
continue;
|
||||
} else if (old_hash == pblock->GetHeaderHash()) {
|
||||
if (old_nonce >= 0xffff0000) {
|
||||
MilliSleep(100);
|
||||
//TODO: FORCE a new getblock!
|
||||
if (fDebug && GetBoolArg("-printmining"))
|
||||
printf("Nothing to do --- uh ih uh ah ah bing bang!!\n");
|
||||
continue;
|
||||
} else
|
||||
pblock->nNonce = old_nonce;
|
||||
} else {
|
||||
old_hash = pblock->GetHeaderHash();
|
||||
old_nonce = 0;
|
||||
}
|
||||
|
||||
if (fDebug && GetBoolArg("-printmining"))
|
||||
printf("Running PrimecoinMiner with %"PRIszu" transactions in block (%u bytes)\n", pblock->vtx.size(),
|
||||
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
|
||||
|
||||
//
|
||||
// Search
|
||||
//
|
||||
int64 nStart = GetTime();
|
||||
bool fNewBlock = true;
|
||||
unsigned int nTriedMultiplier = 0;
|
||||
|
||||
// Primecoin: try to find hash divisible by primorial
|
||||
unsigned int nHashFactor = PrimorialFast(nPrimorialHashFactor);
|
||||
|
||||
// Based on mustyoshi's patch from https://bitcointalk.org/index.php?topic=251850.msg2689981#msg2689981
|
||||
uint256 phash;
|
||||
mpz_class mpzHash;
|
||||
loop {
|
||||
// Fast loop
|
||||
if (pblock->nNonce >= 0xffff0000)
|
||||
break;
|
||||
|
||||
// Check that the hash meets the minimum
|
||||
phash = pblock->GetHeaderHash();
|
||||
if (phash < hashBlockHeaderLimit) {
|
||||
pblock->nNonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the hash is divisible by the fixed primorial
|
||||
mpz_set_uint256(mpzHash.get_mpz_t(), phash);
|
||||
if (!mpz_divisible_ui_p(mpzHash.get_mpz_t(), nHashFactor)) {
|
||||
pblock->nNonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Use the hash that passed the tests
|
||||
break;
|
||||
}
|
||||
if (pblock->nNonce >= 0xffff0000) {
|
||||
old_nonce = 0xffff0000;
|
||||
continue;
|
||||
}
|
||||
// Primecoin: primorial fixed multiplier
|
||||
mpz_class mpzPrimorial;
|
||||
unsigned int nRoundTests = 0;
|
||||
unsigned int nRoundPrimesHit = 0;
|
||||
int64 nPrimeTimerStart = GetTimeMicros();
|
||||
Primorial(nPrimorialMultiplier, mpzPrimorial);
|
||||
|
||||
loop
|
||||
{
|
||||
unsigned int nTests = 0;
|
||||
unsigned int nPrimesHit = 0;
|
||||
unsigned int nChainsHit = 0;
|
||||
|
||||
// Primecoin: adjust round primorial so that the generated prime candidates meet the minimum
|
||||
mpz_class mpzMultiplierMin = mpzPrimeMin * nHashFactor / mpzHash + 1;
|
||||
while (mpzPrimorial < mpzMultiplierMin)
|
||||
{
|
||||
if (!PrimeTableGetNextPrime(nPrimorialMultiplier))
|
||||
error("PrimecoinMiner() : primorial minimum overflow");
|
||||
Primorial(nPrimorialMultiplier, mpzPrimorial);
|
||||
}
|
||||
mpz_class mpzFixedMultiplier;
|
||||
if (mpzPrimorial > nHashFactor) {
|
||||
mpzFixedMultiplier = mpzPrimorial / nHashFactor;
|
||||
} else {
|
||||
mpzFixedMultiplier = 1;
|
||||
}
|
||||
|
||||
// Primecoin: mine for prime chain
|
||||
unsigned int nProbableChainLength;
|
||||
if (MineProbablePrimeChain(*pblock, mpzFixedMultiplier, fNewBlock, nTriedMultiplier, nProbableChainLength, nTests, nPrimesHit, nChainsHit, mpzHash, nPrimorialMultiplier, nSieveGenTime, pindexPrev, block_provider != NULL))
|
||||
{
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
block_provider->submitBlock(pblock);
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
old_nonce = pblock->nNonce + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
///
|
||||
/// ENABLE the following code, if you need data for the perftool
|
||||
///
|
||||
/*if (nProbableChainLength > 0 && nTests > 10)
|
||||
{
|
||||
static CCriticalSection cs;
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
std::ofstream output_file("miner_data");
|
||||
std::ofstream output_file_block("miner_data.blk", std::ofstream::out | std::ofstream::binary);
|
||||
|
||||
::Serialize(output_file_block, *pblock, 0, 0); //writeblock
|
||||
|
||||
output_file << mpzFixedMultiplier.get_str(10) << std::endl;
|
||||
output_file << fNewBlock << std::endl;
|
||||
output_file << nTriedMultiplier << std::endl;
|
||||
output_file << nPrimorialMultiplier << std::endl;
|
||||
output_file << mpzHash.get_str(10) << std::endl;
|
||||
|
||||
output_file.close();
|
||||
output_file_block.close();
|
||||
}
|
||||
}*/
|
||||
|
||||
nRoundTests += nTests;
|
||||
nRoundPrimesHit += nPrimesHit;
|
||||
|
||||
// Meter primes/sec
|
||||
static volatile int64 nPrimeCounter;
|
||||
static volatile int64 nTestCounter;
|
||||
static volatile int64 nChainCounter;
|
||||
static double dChainExpected;
|
||||
int64 nMillisNow = GetTimeMillis();
|
||||
if (nHPSTimerStart == 0)
|
||||
{
|
||||
nHPSTimerStart = nMillisNow;
|
||||
nPrimeCounter = 0;
|
||||
nTestCounter = 0;
|
||||
nChainCounter = 0;
|
||||
dChainExpected = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
// Use atomic increment
|
||||
__sync_add_and_fetch(&nPrimeCounter, nPrimesHit);
|
||||
__sync_add_and_fetch(&nTestCounter, nTests);
|
||||
__sync_add_and_fetch(&nChainCounter, nChainsHit);
|
||||
#else
|
||||
nPrimeCounter += nPrimesHit;
|
||||
nTestCounter += nTests;
|
||||
nChainCounter += nChainsHit;
|
||||
#endif
|
||||
}
|
||||
if (nMillisNow - nHPSTimerStart > 60000)
|
||||
{
|
||||
static CCriticalSection cs;
|
||||
{
|
||||
LOCK(cs);
|
||||
if (nMillisNow - nHPSTimerStart > 60000)
|
||||
{
|
||||
double dPrimesPerMinute = 60000.0 * nPrimeCounter / (nMillisNow - nHPSTimerStart);
|
||||
double dPrimesPerSec = dPrimesPerMinute / 60.0;
|
||||
double dTestsPerSec = 1000.0 * nTestCounter / (nMillisNow - nHPSTimerStart);
|
||||
double dChainsPerMinute = 60000.0 * nChainCounter / (nMillisNow - nHPSTimerStart);
|
||||
double dChainsPerDay = 86400000.0 * dChainExpected / (GetTimeMillis() - nHPSTimerStart);
|
||||
nHPSTimerStart = nMillisNow;
|
||||
nPrimeCounter = 0;
|
||||
nTestCounter = 0;
|
||||
nChainCounter = 0;
|
||||
dChainExpected = 0;
|
||||
static int64 nLogTime = 0;
|
||||
if (nMillisNow - nLogTime > 59000)
|
||||
{
|
||||
nLogTime = nMillisNow;
|
||||
printf("[STATS] %s | %4.0f primes/s, %4.0f tests/s, %4.0f %d-chains/h, %3.3f chains/d\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nLogTime / 1000).c_str(), dPrimesPerSec, dTestsPerSec, dChainsPerMinute * 60.0, nStatsChainLength, dChainsPerDay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
old_nonce = pblock->nNonce;
|
||||
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
if (pblock->nNonce >= 0xffff0000)
|
||||
break;
|
||||
if (pindexPrev != pindexBest/* || (block_provider != NULL && GetTime() - nStart > 200)*/)
|
||||
break;
|
||||
if (thread_id == 0 && block_provider != NULL && (GetTime() - nStart) > 300) { //5 minutes no update? something's wrong -> reconnect!
|
||||
block_provider->forceReconnect();
|
||||
nStart = GetTime();
|
||||
}
|
||||
if (fNewBlock) //aka: sieve's done, we need a updated nonce
|
||||
{
|
||||
// Primecoin: a sieve+primality round completes
|
||||
// Primecoin: estimate time to block
|
||||
const double dTimeExpectedPrev = dTimeExpected;
|
||||
unsigned int nCalcRoundTests = max(1u, nRoundTests);
|
||||
// Make sure the estimated time is very high if only 0 primes were found
|
||||
if (nRoundPrimesHit == 0)
|
||||
nCalcRoundTests *= 1000;
|
||||
int64 nRoundTime = (GetTimeMicros() - nPrimeTimerStart);
|
||||
dTimeExpected = (double) nRoundTime / nCalcRoundTests;
|
||||
double dRoundChainExpected = (double) nRoundTests;
|
||||
for (unsigned int n = 0, nTargetLength = TargetGetLength(pblock->nBits); n < nTargetLength; n++)
|
||||
{
|
||||
double dPrimeProbability = EstimateCandidatePrimeProbability(nPrimorialMultiplier, n);
|
||||
dTimeExpected = dTimeExpected / max(0.01, dPrimeProbability);
|
||||
dRoundChainExpected *= dPrimeProbability;
|
||||
}
|
||||
dChainExpected += dRoundChainExpected;
|
||||
if (fDebug && GetBoolArg("-printmining"))
|
||||
{
|
||||
double dPrimeProbabilityBegin = EstimateCandidatePrimeProbability(nPrimorialMultiplier, 0);
|
||||
unsigned int nTargetLength = TargetGetLength(pblock->nBits);
|
||||
double dPrimeProbabilityEnd = EstimateCandidatePrimeProbability(nPrimorialMultiplier, nTargetLength - 1);
|
||||
printf("PrimecoinMiner() : Round primorial=%u tests=%u primes=%u time=%uus pprob=%1.6f pprob2=%1.6f tochain=%6.3fd expect=%3.9f\n", nPrimorialMultiplier, nRoundTests, nRoundPrimesHit, (unsigned int) nRoundTime, dPrimeProbabilityBegin, dPrimeProbabilityEnd, ((dTimeExpected/1000000.0))/86400.0, dRoundChainExpected);
|
||||
}
|
||||
|
||||
// Primecoin: update time and nonce
|
||||
//pblock->nTime = max(pblock->nTime, (unsigned int) GetAdjustedTime());
|
||||
pblock->nTime = max(pblock->nTime, block_provider->GetAdjustedTimeWithOffset(thread_id));
|
||||
pblock->nNonce++;
|
||||
loop {
|
||||
// Fast loop
|
||||
if (pblock->nNonce >= 0xffff0000)
|
||||
break;
|
||||
|
||||
// Check that the hash meets the minimum
|
||||
phash = pblock->GetHeaderHash();
|
||||
if (phash < hashBlockHeaderLimit) {
|
||||
pblock->nNonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check that the hash is divisible by the fixed primorial
|
||||
mpz_set_uint256(mpzHash.get_mpz_t(), phash);
|
||||
if (!mpz_divisible_ui_p(mpzHash.get_mpz_t(), nHashFactor)) {
|
||||
pblock->nNonce++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Use the hash that passed the tests
|
||||
break;
|
||||
}
|
||||
if (pblock->nNonce >= 0xffff0000)
|
||||
break;
|
||||
|
||||
// Primecoin: reset sieve+primality round timer
|
||||
nPrimeTimerStart = GetTimeMicros();
|
||||
if (dTimeExpected > dTimeExpectedPrev)
|
||||
fIncrementPrimorial = !fIncrementPrimorial;
|
||||
|
||||
// Primecoin: primorial always needs to be incremented if only 0 primes were found
|
||||
if (nRoundPrimesHit == 0)
|
||||
fIncrementPrimorial = true;
|
||||
|
||||
nRoundTests = 0;
|
||||
nRoundPrimesHit = 0;
|
||||
|
||||
// Primecoin: dynamic adjustment of primorial multiplier
|
||||
if (fIncrementPrimorial)
|
||||
{
|
||||
if (!PrimeTableGetNextPrime(nPrimorialMultiplier))
|
||||
error("PrimecoinMiner() : primorial increment overflow");
|
||||
}
|
||||
else if (nPrimorialMultiplier > nPrimorialHashFactor)
|
||||
{
|
||||
if (!PrimeTableGetPreviousPrime(nPrimorialMultiplier))
|
||||
error("PrimecoinMiner() : primorial decrement overflow");
|
||||
}
|
||||
Primorial(nPrimorialMultiplier, mpzPrimorial);
|
||||
}
|
||||
}
|
||||
} }
|
||||
catch (boost::thread_interrupted)
|
||||
{
|
||||
printf("PrimecoinMiner terminated\n");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,10 +26,7 @@
|
|||
|
||||
// <START> be compatible to original code (not actually used!)
|
||||
#include "txdb.h"
|
||||
#include "walletdb.h"
|
||||
#include "wallet.h"
|
||||
#include "ui_interface.h"
|
||||
CWallet *pwalletMain;
|
||||
CClientUIInterface uiInterface;
|
||||
void StartShutdown() {
|
||||
exit(0);
|
||||
|
@ -41,8 +38,7 @@ void StartShutdown() {
|
|||
*********************************/
|
||||
|
||||
extern CBlockIndex *pindexBest;
|
||||
extern void BitcoinMiner(CWallet *pwallet,
|
||||
CBlockProvider *CBlockProvider,
|
||||
extern void BitcoinMiner(CBlockProvider *CBlockProvider,
|
||||
unsigned int thread_id);
|
||||
extern bool fPrintToConsole;
|
||||
extern bool fDebug;
|
||||
|
@ -216,7 +212,7 @@ public:
|
|||
_master->wait_for_master();
|
||||
std::cout << "[WORKER" << _id << "] GoGoGo!" << std::endl;
|
||||
boost::this_thread::sleep(boost::posix_time::seconds(2));
|
||||
BitcoinMiner(NULL, _bprovider, _id);
|
||||
BitcoinMiner(_bprovider, _id);
|
||||
std::cout << "[WORKER" << _id << "] Bye Bye!" << std::endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,45 +121,18 @@ DEBUGFLAGS=
|
|||
# CXXFLAGS can be specified on the make command line, so we use xCXXFLAGS that only
|
||||
# adds some defaults in front. Unfortunately, CXXFLAGS=... $(CXXFLAGS) does not work.
|
||||
xCXXFLAGS=-O2 -pthread -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter \
|
||||
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS)
|
||||
$(DEBUGFLAGS) $(DEFS) $(HARDENING) $(CXXFLAGS) -march=native
|
||||
|
||||
# LDFLAGS can be specified on the make command line, so we use xLDFLAGS that only
|
||||
# adds some defaults in front. Unfortunately, LDFLAGS=... $(LDFLAGS) does not work.
|
||||
xLDFLAGS=$(LDHARDENING) $(LDFLAGS)
|
||||
|
||||
OBJS= \
|
||||
leveldb/libleveldb.a \
|
||||
obj/alert.o \
|
||||
obj/version.o \
|
||||
obj/checkpoints.o \
|
||||
obj/netbase.o \
|
||||
obj/addrman.o \
|
||||
obj/crypter.o \
|
||||
obj/key.o \
|
||||
obj/db.o \
|
||||
obj/keystore.o \
|
||||
obj/main.o \
|
||||
obj/net.o \
|
||||
obj/protocol.o \
|
||||
obj/bitcoinrpc.o \
|
||||
obj/rpcdump.o \
|
||||
obj/rpcnet.o \
|
||||
obj/rpcmining.o \
|
||||
obj/rpcwallet.o \
|
||||
obj/rpcblockchain.o \
|
||||
obj/rpcrawtransaction.o \
|
||||
obj/script.o \
|
||||
obj/sync.o \
|
||||
obj/util.o \
|
||||
obj/wallet.o \
|
||||
obj/walletdb.o \
|
||||
obj/hash.o \
|
||||
obj/bloom.o \
|
||||
obj/noui.o \
|
||||
obj/leveldb.o \
|
||||
obj/txdb.o \
|
||||
obj/prime.o \
|
||||
obj/checkpointsync.o
|
||||
obj/bitcoinminer.o
|
||||
|
||||
all: primeminer
|
||||
|
||||
|
@ -170,11 +143,11 @@ test check: test_primecoin FORCE
|
|||
# LevelDB support
|
||||
#
|
||||
MAKEOVERRIDES =
|
||||
LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a
|
||||
DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
|
||||
DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
|
||||
leveldb/libleveldb.a:
|
||||
@echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && cd ..
|
||||
#LIBS += $(CURDIR)/leveldb/libleveldb.a $(CURDIR)/leveldb/libmemenv.a
|
||||
#DEFS += $(addprefix -I,$(CURDIR)/leveldb/include)
|
||||
#DEFS += $(addprefix -I,$(CURDIR)/leveldb/helpers)
|
||||
#leveldb/libleveldb.a:
|
||||
# @echo "Building LevelDB ..." && cd leveldb && $(MAKE) CC=$(CC) CXX=$(CXX) OPT="$(xCXXFLAGS)" libleveldb.a libmemenv.a && cd ..
|
||||
|
||||
# auto-generated dependencies:
|
||||
-include obj/*.P
|
||||
|
|
Loading…
Reference in a new issue