Example #1
0
bool MineProbablePrimeChainFast(PrimecoinBlockHeader &header,
                                CSieveOfEratosthenesL1Ext *sieve,
                                mpz_class &blockHeaderHash,
                                mpz_class &primorial,
                                unsigned int& nProbableChainLength,
                                unsigned int& nTests,
                                unsigned int& nPrimesHit,
                                CPrimalityTestParams &testParams,
                                const PrimeSource &primeSource,
                                uint64_t *foundChains)
{
  timeMark sieveBegin = getTimeMark();
  mpz_class hashMultiplier = blockHeaderHash*primorial;
  sieve->reset(gSieveSize, chainLengthFromBits(header.bits), gWeaveDepth, hashMultiplier);
  sieve->Weave();
  timeMark sieveEnd = getTimeMark();  
  if (gDebug) {
    fprintf(stderr,
            " * sieve %.3lfmsec: %u@%u/%u ",
            usDiff(sieveBegin, sieveEnd) / 1000.0,
            sieve->GetCandidateCount(),
            gSieveSize,
            gWeaveDepth);
  }  
  
  nTests = 0;
  nPrimesHit = 0;
  unsigned nTriedMultiplier;
  mpz_class bnChainOrigin;
  
  unsigned int &nChainLength = testParams.chainLength;
  unsigned int &nCandidateType = testParams.candidateType;      
  sieve->resetCandidateIterator();
  while (true) {
    nTests++;
    if (!sieve->GetNextCandidateMultiplier(nTriedMultiplier, nCandidateType)) {
      timeMark primalityTestEnd = getTimeMark();
      if (gDebug) {
        fprintf(stderr,
                " primality Fermat test %.3lfmsec\n",
                usDiff(sieveEnd, primalityTestEnd) / 1000.0);
      }
      
      return false;
    }
    
    bnChainOrigin = hashMultiplier;
    bnChainOrigin *= nTriedMultiplier;
    nChainLength = 0;
    if (ProbablePrimeChainTestFast(bnChainOrigin, testParams)) {
      uint8_t buffer[256];
      BIGNUM *xxx = 0;
      mpz_class targetMultiplier = primorial*nTriedMultiplier;
      BN_dec2bn(&xxx, targetMultiplier.get_str().c_str());
      BN_bn2mpi(xxx, buffer);
      header.multiplier[0] = buffer[3];
      std::reverse_copy(buffer+4, buffer+4+buffer[3], header.multiplier+1);
      fprintf(stderr, "targetMultiplier=%s\n", targetMultiplier.get_str().c_str());
      return true;
    }
    
    nProbableChainLength = nChainLength;
    if (chainLengthFromBits(nProbableChainLength) >= 1) {
      foundChains[chainLengthFromBits(nProbableChainLength)]++;
      nPrimesHit++;
    }
  }
  
  return false;
}
// Mine probable prime chain of form: n = h * p# +/- 1
bool MineProbablePrimeChain(Reap_CPU_param* state, Work& tempwork, CSieveOfEratosthenes& psieve, mpz_class& mpzFixedMultiplier, bool& fNewBlock, unsigned int& nTriedMultiplier, unsigned int& nProbableChainLength, unsigned int& nTests, unsigned int& nPrimesHit, unsigned int& nChainsHit, mpz_class& mpzHash, unsigned int nPrimorialMultiplier)
{
    nProbableChainLength = 0;
    nPrimesHit = 0;
    nChainsHit = 0;
    //const unsigned int nBits = block.nBits;
	const unsigned int nBits = *(uint*)&tempwork.data[72];
	
	bool use_gpu_fermat_test = globalconfs.coin.config.GetValue<bool>("use_gpu_fermat_test");

    if (fNewBlock && psieve.inited)
    {
        // Must rebuild the sieve
		psieve.Deinit();
    }
    fNewBlock = false;

    int64 nStart; // microsecond timer
    if (!psieve.inited)
    {
        // Build sieve
        nStart = ticker()*1000;
		psieve.InitAndWeave(state, nSieveSize, nBits, mpzHash, mpzFixedMultiplier);
        if (globalconfs.coin.config.GetValue<bool>("debug"))
            printf("MineProbablePrimeChain() : new sieve (%lu/%u) ready in %uus\n", psieve.CandidateList.size(), nSieveSize, (unsigned int) (ticker()*1000 - nStart));
    }

    mpz_class mpzHashMultiplier = mpzHash * mpzFixedMultiplier;
    mpz_class mpzChainOrigin;

    // Determine the sequence number of the round primorial
    unsigned int nPrimorialSeq = 0;
    while (vPrimes[nPrimorialSeq + 1] <= nPrimorialMultiplier)
        nPrimorialSeq++;

    // Allocate GMP variables for primality tests
    CPrimalityTestParams testParams(nBits, nPrimorialSeq);
    nStart = ticker()*1000;

    // References to counters;
    unsigned int& nChainLengthCunningham1 = testParams.nChainLengthCunningham1;
    unsigned int& nChainLengthCunningham2 = testParams.nChainLengthCunningham2;
    unsigned int& nChainLengthBiTwin = testParams.nChainLengthBiTwin;
	
	//cout << "PSIEVIOSIE" << psieve.CandidateList.size() << endl;
	
	for(uint i=0; i<psieve.CandidateList.size(); ++i)
    {
		nTriedMultiplier = psieve.CandidateList[i]&0x3FFFFFFFU;
		uint sievenumber = psieve.CandidateList[i]>>30;
		if (sievenumber == 0)
			sievenumber=3;
		if (nTriedMultiplier == 0) //will crash otherwise
			continue;
		++nTests;
		if (tempwork.time != current_work.time)
		{
			//cout << "Tempwork.time != curnetopqi" << tempwork.time << " " << current_work.time << endl;
			break;
		}
        mpzChainOrigin = mpzHashMultiplier * (nTriedMultiplier&0x3FFFFFFFU);
        nChainLengthCunningham1 = 0;
        nChainLengthCunningham2 = 0;
        nChainLengthBiTwin = 0;
        if (ProbablePrimeChainTestFast(mpzChainOrigin, testParams, sievenumber, use_gpu_fermat_test))
        {
			mpz_t mpzPrimeChainMultiplier; mpz_init(mpzPrimeChainMultiplier);
			mpz_mul_ui(mpzPrimeChainMultiplier,mpzFixedMultiplier.get_mpz_t(),nTriedMultiplier);
			{
				//gmp_printf("Found chain! Mult: %Zx\n",mpzPrimeChainMultiplier);
				vector<uchar> auxdata = XPM_create_auxdata(&mpzPrimeChainMultiplier);
				CPU_Got_share(state,tempwork,auxdata);
			}
			mpz_clear(mpzPrimeChainMultiplier);

            nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
            return true;
        }
        nProbableChainLength = std::max(std::max(nChainLengthCunningham1, nChainLengthCunningham2), nChainLengthBiTwin);
        if(TargetGetLength(nProbableChainLength) >= 1)
            nPrimesHit++;
        if(TargetGetLength(nProbableChainLength) >= nStatsChainLength)
            nChainsHit++;
    }

	// power tests completed for the sieve
	//if (fDebug && GetBoolArg("-printmining"))
		//printf("MineProbablePrimeChain() : %u tests (%u primes and %u %d-chains) in %uus\n", nTests, nPrimesHit, nChainsHit, nStatsChainLength, (unsigned int) (GetTimeMicros() - nStart));
	psieve.Deinit();
	fNewBlock = true; // notify caller to change nonce
	return false; // stop as new block arrived
}