Permalink
Browse files

Primecoin: Faster version of primality test for miner

  • Loading branch information...
sunnyking committed Jul 27, 2013
1 parent 778bba0 commit 2f6545476673f6438df41ca190ca6867a730c77b
Showing with 59 additions and 16 deletions.
  1. +2 −3 src/main.cpp
  2. +42 −9 src/prime.cpp
  3. +15 −4 src/prime.h
View
@@ -4711,9 +4711,8 @@ void static BitcoinMiner(CWallet *pwallet)
// Primecoin: estimate time to block
int64 nRoundTime = (GetTimeMicros() - nPrimeTimerStart);
nTimeExpected = nRoundTime / max(1u, nRoundTests);
nTimeExpected = nTimeExpected * max(1u, nRoundTests) / max(1u, nRoundPrimesHit);
for (unsigned int n = 1; n < TargetGetLength(pblock->nBits); n++)
nTimeExpected = nTimeExpected * max(1u, nRoundTests) * 3 / max(1u, nRoundPrimesHit);
for (unsigned int n = 0; n < TargetGetLength(pblock->nBits); n++)
nTimeExpected = nTimeExpected * max(1u, nRoundTests) / max(1u, nRoundPrimesHit);
if (fDebug && GetBoolArg("-printmining"))
printf("PrimecoinMiner() : Round primorial=%u tests=%u primes=%u time=%uus expect=%6.3fd\n", nPrimorialMultiplier, nRoundTests, nRoundPrimesHit, (unsigned int) nRoundTime, ((double)(nTimeExpected/1000000))/86400.0);
View
@@ -331,6 +331,40 @@ bool ProbablePrimeChainTest(const CBigNum& bnPrimeChainOrigin, unsigned int nBit
return (nChainLengthCunningham1 >= nBits || nChainLengthCunningham2 >= nBits || nChainLengthBiTwin >= nBits);
}
// Test probable prime chain for: nOrigin (miner version - for miner use only)
// Return value:
// true - Probable prime chain found (nChainLength meeting target)
// false - prime chain too short (nChainLength not meeting target)
static bool ProbablePrimeChainTestForMiner(const CBigNum& bnPrimeChainOrigin, unsigned int nBits, unsigned nCandidateType, unsigned int& nChainLength)
{
nChainLength = 0;
// Test for Cunningham Chain of first kind
if (nCandidateType == PRIME_CHAIN_CUNNINGHAM1)
ProbableCunninghamChainTest(bnPrimeChainOrigin-1, true, false, nChainLength);
// Test for Cunningham Chain of second kind
else if (nCandidateType == PRIME_CHAIN_CUNNINGHAM2)
ProbableCunninghamChainTest(bnPrimeChainOrigin+1, false, false, nChainLength);
else
{
unsigned int nChainLengthCunningham1 = 0;
unsigned int nChainLengthCunningham2 = 0;
if (ProbableCunninghamChainTest(bnPrimeChainOrigin-1, true, false, nChainLengthCunningham1))
{
ProbableCunninghamChainTest(bnPrimeChainOrigin+1, false, false, nChainLengthCunningham2);
// Figure out BiTwin Chain length
// BiTwin Chain allows a single prime at the end for odd length chain
nChainLength =
(TargetGetLength(nChainLengthCunningham1) > TargetGetLength(nChainLengthCunningham2))?
(nChainLengthCunningham2 + TargetFromInt(TargetGetLength(nChainLengthCunningham2)+1)) :
(nChainLengthCunningham1 + TargetFromInt(TargetGetLength(nChainLengthCunningham1)));
}
}
return (nChainLength >= nBits);
}
// Sieve for mining
boost::thread_specific_ptr<CSieveOfEratosthenes> psieve;
boost::thread_specific_ptr<CSieveControl> psievectrl;
@@ -386,26 +420,25 @@ bool MineProbablePrimeChain(CBlock& block, CBigNum& bnFixedMultiplier, bool& fNe
while (nCurrent - nStart < 10000 && nCurrent >= nStart && pindexPrev == pindexBest)
{
nTests++;
if (!psieve->GetNextCandidateMultiplier(nTriedMultiplier))
unsigned int nCandidateType;
if (!psieve->GetNextCandidateMultiplier(nTriedMultiplier, nCandidateType))
{
// power tests completed for the sieve
psieve.reset();
fNewBlock = true; // notify caller to change nonce
return false;
}
bnChainOrigin = CBigNum(block.GetHeaderHash()) * bnFixedMultiplier * nTriedMultiplier;
unsigned int nChainLengthCunningham1 = 0;
unsigned int nChainLengthCunningham2 = 0;
unsigned int nChainLengthBiTwin = 0;
if (ProbablePrimeChainTest(bnChainOrigin, block.nBits, false, nChainLengthCunningham1, nChainLengthCunningham2, nChainLengthBiTwin))
unsigned int nChainLength = 0;
if (ProbablePrimeChainTestForMiner(bnChainOrigin, block.nBits, nCandidateType, nChainLength))
{
block.bnPrimeChainMultiplier = bnFixedMultiplier * nTriedMultiplier;
printf("Probable prime chain found for block=%s!!\n Target: %s\n Length: (%s %s %s)\n", block.GetHash().GetHex().c_str(),
TargetToString(block.nBits).c_str(), TargetToString(nChainLengthCunningham1).c_str(), TargetToString(nChainLengthCunningham2).c_str(), TargetToString(nChainLengthBiTwin).c_str());
nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
printf("Probable prime chain found for block=%s!!\n Target: %s\n Chain: %s\n", block.GetHash().GetHex().c_str(),
TargetToString(block.nBits).c_str(), GetPrimeChainName(nCandidateType, nChainLength).c_str());
nProbableChainLength = nChainLength;
return true;
}
nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
nProbableChainLength = nChainLength;
if(TargetGetLength(nProbableChainLength) >= 1)
nPrimesHit++;
if(TargetGetLength(nProbableChainLength) >= nStatsChainLength)
View
@@ -126,7 +126,7 @@ class CSieveOfEratosthenes
// Return values:
// True - found next candidate; nVariableMultiplier has the candidate
// False - scan complete, no more candidate and reset scan
bool GetNextCandidateMultiplier(unsigned int& nVariableMultiplier)
bool GetNextCandidateMultiplier(unsigned int& nVariableMultiplier, unsigned int& nCandidateType)
{
loop
{
@@ -136,11 +136,22 @@ class CSieveOfEratosthenes
nCandidateMultiplier = 0;
return false;
}
if (!vfCompositeCunningham1[nCandidateMultiplier] ||
!vfCompositeCunningham2[nCandidateMultiplier] ||
!vfCompositeBiTwin[nCandidateMultiplier])
if (!vfCompositeBiTwin[nCandidateMultiplier])
{
nVariableMultiplier = nCandidateMultiplier;
nCandidateType = PRIME_CHAIN_BI_TWIN;
return true;
}
if (!vfCompositeCunningham1[nCandidateMultiplier])
{
nVariableMultiplier = nCandidateMultiplier;
nCandidateType = PRIME_CHAIN_CUNNINGHAM1;
return true;
}
if (!vfCompositeCunningham2[nCandidateMultiplier])
{
nVariableMultiplier = nCandidateMultiplier;
nCandidateType = PRIME_CHAIN_CUNNINGHAM2;
return true;
}
}

0 comments on commit 2f65454

Please sign in to comment.