void* Reap_CPU_V1(void* param) { Reap_CPU_param* state = (Reap_CPU_param*)param; Work tempwork; tempwork.time = 13371337; uint8_t tempdata[512]; memset(tempdata, 0, 512); uint8_t finalhash[32]; uint8_t hash_results[1] = {}; uint32_t current_server_id; while(!shutdown_now) { if (current_work.old) { Wait_ms(20); continue; } if (tempwork.time != current_work.time) { pthread_mutex_lock(¤t_work_mutex); tempwork = current_work; pthread_mutex_unlock(¤t_work_mutex); memcpy(tempdata, &tempwork.data[0], 128); *(uint32_t*)&tempdata[100] = state->thread_id; current_server_id = tempwork.server_id; } *(uint64_t*)&tempdata[76] = tempwork.ntime_at_getwork + (ticker()-tempwork.time)/1000; for(uint32_t h=0; h<CPU_BATCH_SIZE; ++h) { BlockHash_1_mine_V1(tempdata, finalhash, hash_results); if (hash_results[0]) { BlockHash_1(tempdata, finalhash); if (finalhash[30] != 0 || finalhash[31] != 0) cpu_shares_hwinvalid++; else cpu_shares_hwvalid++; if (CPU_Hash_Below_Target(finalhash, &tempwork.target_share[0])) CPU_Got_share(state,tempdata,tempwork.target_share,current_server_id); } ++*(uint32_t*)&tempdata[108]; } state->hashes += CPU_BATCH_SIZE; } pthread_exit(NULL); return NULL; }
bool MinePrime(Reap_CPU_param* state, Work& tempwork) { uchar* tempdata = &tempwork.data[0]; uchar hash[32]; mysha256(hash,tempdata,80); mysha256(hash,hash,32); //does this need byte flipping? uint bits = *(uint*)&tempdata[72]; if (!(hash[31] & 0x80)) return false; //hash is too small, abort Mpz_w hashnum; set_mpz_to_hash(&hashnum.n, hash); if (mpz_fdiv_ui(hashnum.n, 2*3) != 0) return false; bool found=false; //5431526412865007455 mpz_t factor; mpz_init_set_str(factor, "5431526412865007455", 10); mpz_mul(hashnum.n,hashnum.n,factor); uint remainders[MAX_SIEVE_AMOUNT] = {}; for(int i=0; i<MAX_SIEVE_AMOUNT; ++i) { remainders[i] = mpz_fdiv_ui(hashnum.n,Primes::v[i]); } mpz_t newhashnum; mpz_init(newhashnum); for(uint h=1; h<500; ++h) { mpz_add(newhashnum,newhashnum,hashnum.n); uint c1=0,c2=0,tw=0; uint sievenumber = 0; for(uint i=16; i<MAX_SIEVE_AMOUNT; ++i) { sievenumber |= Sieve::Get(i,remainders[i]*h%Primes::v[i])^3; } sievenumber ^= 3; //cout << sievenumber << endl;; if (sievenumber == 0) continue; //TODO: fix second parameter, it should be bits! AllChainTest(&newhashnum, 0, true, &c1, &c2, &tw, sievenumber); uint c1_i = TargetGetLength(c1); uint c2_i = TargetGetLength(c2); uint tw_i = TargetGetLength(tw); const int minlength=5; /*{ if (c1_i >= minlength) cout << "First kind: " << c1_i << endl; if (c2_i >= minlength) cout << "Second kind: " << c2_i << endl; if (tw_i >= minlength) cout << "Twin kind: " << tw_i << endl; }*/ ++chainspersec[c1_i]; ++chainspersec[c2_i]; ++chainspersec[tw_i]; ++totalpersec; found = (c1_i >= minlength || c2_i >= minlength || tw_i >= minlength); if (found) { mpz_mul_ui(factor,factor,h); vector<uchar> auxdata = XPM_create_auxdata(&factor); Share share; CPU_Got_share(state,tempwork,auxdata);//tempdata,tempwork.target_share,current_server_id,tempwork.dataid,auxdata); } } return found; }
// 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 }