prime.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. #include "config.h"
  2. #include <stdbool.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <sys/time.h>
  7. #include <gmp.h>
  8. #include "compat.h"
  9. #include "miner.h"
  10. #define nMaxSieveSize 1000000u
  11. #define nPrimeTableLimit 100000u //nMaxSieveSize
  12. #define PRIME_COUNT 9592 //78498
  13. static
  14. unsigned vPrimes[PRIME_COUNT];
  15. mpz_t vPrimorials[PRIME_COUNT];
  16. static
  17. int64_t GetTimeMicros()
  18. {
  19. struct timeval tv;
  20. cgtime(&tv);
  21. return (tv.tv_sec * 1000000) + tv.tv_usec;
  22. }
  23. static
  24. int64_t GetTimeMillis()
  25. {
  26. return GetTimeMicros() / 1000;
  27. }
  28. static
  29. bool error(const char *fmt, ...)
  30. {
  31. puts(fmt); // FIXME
  32. return false;
  33. }
  34. static
  35. void GeneratePrimeTable()
  36. {
  37. mpz_t bnOne;
  38. mpz_init_set_ui(bnOne, 1);
  39. mpz_t *bnLastPrimorial = &bnOne;
  40. unsigned i = 0;
  41. // Generate prime table using sieve of Eratosthenes
  42. bool vfComposite[nPrimeTableLimit] = {false};
  43. for (unsigned int nFactor = 2; nFactor * nFactor < nPrimeTableLimit; nFactor++)
  44. {
  45. if (vfComposite[nFactor])
  46. continue;
  47. for (unsigned int nComposite = nFactor * nFactor; nComposite < nPrimeTableLimit; nComposite += nFactor)
  48. vfComposite[nComposite] = true;
  49. }
  50. for (unsigned int n = 2; n < nPrimeTableLimit; n++)
  51. if (!vfComposite[n])
  52. {
  53. vPrimes[i] = n;
  54. mpz_init(vPrimorials[i]);
  55. mpz_mul_ui(vPrimorials[i], *bnLastPrimorial, n);
  56. bnLastPrimorial = &vPrimorials[i];
  57. ++i;
  58. }
  59. printf("GeneratePrimeTable() : prime table [1, %d] generated with %lu primes\n", nPrimeTableLimit, (unsigned long)i);
  60. }
  61. #define nFractionalBits 24
  62. #define TARGET_FRACTIONAL_MASK ((1u << nFractionalBits) - 1)
  63. #define TARGET_LENGTH_MASK (~TARGET_FRACTIONAL_MASK)
  64. // Check Fermat probable primality test (2-PRP): 2 ** (n-1) = 1 (mod n)
  65. // true: n is probable prime
  66. // false: n is composite; set fractional length in the nLength output
  67. static
  68. bool FermatProbablePrimalityTest(mpz_t *n, unsigned int *pnLength)
  69. {
  70. mpz_t a, e, r;
  71. mpz_init_set_ui(a, 2); // base; Fermat witness
  72. mpz_init(e);
  73. mpz_sub_ui(e, *n, 1);
  74. mpz_init(r);
  75. mpz_powm(r, a, e, *n);
  76. if (!mpz_cmp_ui(r, 1))
  77. return true;
  78. // Failed Fermat test, calculate fractional length
  79. // nFractionalLength = ( (n-r) << nFractionalBits ) / n
  80. mpz_sub(r, *n, r);
  81. mpz_mul_2exp(r, r, nFractionalBits);
  82. mpz_fdiv_q(r, r, *n);
  83. unsigned int nFractionalLength = mpz_get_ui(r);
  84. if (nFractionalLength >= (1 << nFractionalBits))
  85. return error("FermatProbablePrimalityTest() : fractional assert");
  86. *pnLength = (*pnLength & TARGET_LENGTH_MASK) | nFractionalLength;
  87. return false;
  88. }
  89. static
  90. unsigned int TargetGetLength(unsigned int nBits)
  91. {
  92. return ((nBits & TARGET_LENGTH_MASK) >> nFractionalBits);
  93. }
  94. static
  95. void TargetIncrementLength(unsigned int *pnBits)
  96. {
  97. *pnBits += (1 << nFractionalBits);
  98. }
  99. // Test probable primality of n = 2p +/- 1 based on Euler, Lagrange and Lifchitz
  100. // fSophieGermain:
  101. // true: n = 2p+1, p prime, aka Cunningham Chain of first kind
  102. // false: n = 2p-1, p prime, aka Cunningham Chain of second kind
  103. // Return values
  104. // true: n is probable prime
  105. // false: n is composite; set fractional length in the nLength output
  106. static
  107. bool EulerLagrangeLifchitzPrimalityTest(mpz_t *n, bool fSophieGermain, unsigned int *pnLength)
  108. {
  109. mpz_t a, e, r;
  110. mpz_init_set_ui(a, 2);
  111. mpz_init(e);
  112. mpz_sub_ui(e, *n, 1);
  113. mpz_fdiv_q_2exp(e, e, 1);
  114. mpz_init(r);
  115. mpz_powm(r, a, e, *n);
  116. unsigned nMod8 = mpz_fdiv_ui(*n, 8);
  117. bool fPassedTest = false;
  118. if (fSophieGermain && (nMod8 == 7)) // Euler & Lagrange
  119. fPassedTest = !mpz_cmp_ui(r, 1);
  120. else if (nMod8 == (fSophieGermain ? 3 : 5)) // Lifchitz
  121. {
  122. mpz_t mp;
  123. mpz_init_set_ui(mp, 1);
  124. mpz_add(mp, r, mp);
  125. fPassedTest = !mpz_cmp(mp, *n);
  126. mpz_clear(mp);
  127. }
  128. else if ((!fSophieGermain) && (nMod8 == 1)) // LifChitz
  129. fPassedTest = !mpz_cmp_ui(r, 1);
  130. else
  131. return error("EulerLagrangeLifchitzPrimalityTest() : invalid n %% 8 = %d, %s", nMod8, (fSophieGermain? "first kind" : "second kind"));
  132. if (fPassedTest)
  133. return true;
  134. // Failed test, calculate fractional length
  135. // derive Fermat test remainder
  136. mpz_mul(r, r, r);
  137. mpz_fdiv_r(r, r, *n);
  138. // nFractionalLength = ( (n-r) << nFractionalBits ) / n
  139. mpz_sub(r, *n, r);
  140. mpz_mul_2exp(r, r, nFractionalBits);
  141. mpz_fdiv_q(r, r, *n);
  142. unsigned int nFractionalLength = mpz_get_ui(r);
  143. if (nFractionalLength >= (1 << nFractionalBits))
  144. return error("EulerLagrangeLifchitzPrimalityTest() : fractional assert");
  145. *pnLength = (*pnLength & TARGET_LENGTH_MASK) | nFractionalLength;
  146. return false;
  147. }
  148. // Test Probable Cunningham Chain for: n
  149. // fSophieGermain:
  150. // true - Test for Cunningham Chain of first kind (n, 2n+1, 4n+3, ...)
  151. // false - Test for Cunningham Chain of second kind (n, 2n-1, 4n-3, ...)
  152. // Return value:
  153. // true - Probable Cunningham Chain found (length at least 2)
  154. // false - Not Cunningham Chain
  155. static
  156. bool ProbableCunninghamChainTest(mpz_t *n, bool fSophieGermain, bool fFermatTest, unsigned int *pnProbableChainLength)
  157. {
  158. *pnProbableChainLength = 0;
  159. mpz_t N;
  160. mpz_init_set(N, *n);
  161. // Fermat test for n first
  162. if (!FermatProbablePrimalityTest(&N, pnProbableChainLength))
  163. return false;
  164. // Euler-Lagrange-Lifchitz test for the following numbers in chain
  165. while (true)
  166. {
  167. TargetIncrementLength(pnProbableChainLength);
  168. mpz_add(N, N, N);
  169. mpz_add_ui(N, N, (fSophieGermain? 1 : (-1)));
  170. if (fFermatTest)
  171. {
  172. if (!FermatProbablePrimalityTest(&N, pnProbableChainLength))
  173. break;
  174. }
  175. else
  176. {
  177. if (!EulerLagrangeLifchitzPrimalityTest(&N, fSophieGermain, pnProbableChainLength))
  178. break;
  179. }
  180. }
  181. return (TargetGetLength(*pnProbableChainLength) >= 2);
  182. }
  183. static
  184. unsigned int TargetFromInt(unsigned int nLength)
  185. {
  186. return (nLength << nFractionalBits);
  187. }
  188. // Test probable prime chain for: nOrigin
  189. // Return value:
  190. // true - Probable prime chain found (one of nChainLength meeting target)
  191. // false - prime chain too short (none of nChainLength meeting target)
  192. static
  193. bool ProbablePrimeChainTest(mpz_t *bnPrimeChainOrigin, unsigned int nBits, bool fFermatTest, unsigned int *pnChainLengthCunningham1, unsigned int *pnChainLengthCunningham2, unsigned int *pnChainLengthBiTwin)
  194. {
  195. *pnChainLengthCunningham1 = 0;
  196. *pnChainLengthCunningham2 = 0;
  197. *pnChainLengthBiTwin = 0;
  198. mpz_t mp;
  199. mpz_init(mp);
  200. // Test for Cunningham Chain of first kind
  201. mpz_sub_ui(mp, *bnPrimeChainOrigin, 1);
  202. ProbableCunninghamChainTest(&mp, true, fFermatTest, pnChainLengthCunningham1);
  203. // Test for Cunningham Chain of second kind
  204. mpz_add_ui(mp, *bnPrimeChainOrigin, 1);
  205. ProbableCunninghamChainTest(&mp, false, fFermatTest, pnChainLengthCunningham2);
  206. // Figure out BiTwin Chain length
  207. // BiTwin Chain allows a single prime at the end for odd length chain
  208. *pnChainLengthBiTwin = (TargetGetLength(*pnChainLengthCunningham1) > TargetGetLength(*pnChainLengthCunningham2)) ? (*pnChainLengthCunningham2 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham2)+1)) : (*pnChainLengthCunningham1 + TargetFromInt(TargetGetLength(*pnChainLengthCunningham1)));
  209. return (*pnChainLengthCunningham1 >= nBits || *pnChainLengthCunningham2 >= nBits || *pnChainLengthBiTwin >= nBits);
  210. }
  211. struct SieveOfEratosthenes {
  212. bool valid;
  213. unsigned int nSieveSize; // size of the sieve
  214. unsigned int nBits; // target of the prime chain to search for
  215. mpz_t hashBlockHeader; // block header hash
  216. mpz_t bnFixedFactor; // fixed factor to derive the chain
  217. // bitmaps of the sieve, index represents the variable part of multiplier
  218. bool vfCompositeCunningham1[1000000];
  219. bool vfCompositeCunningham2[1000000];
  220. bool vfCompositeBiTwin[1000000];
  221. unsigned int nPrimeSeq; // prime sequence number currently being processed
  222. unsigned int nCandidateMultiplier; // current candidate for power test
  223. };
  224. static
  225. void psieve_reset(struct SieveOfEratosthenes *psieve)
  226. {
  227. // FIXME: if valid, free stuff?
  228. psieve->valid = false;
  229. }
  230. static
  231. void psieve_init(struct SieveOfEratosthenes *psieve, unsigned nSieveSize, unsigned nBits, mpz_t *hashBlockHeader, mpz_t *bnFixedMultiplier)
  232. {
  233. *psieve = (struct SieveOfEratosthenes){
  234. .valid = true,
  235. .nSieveSize = nSieveSize,
  236. .nBits = nBits,
  237. };
  238. mpz_init_set(psieve->hashBlockHeader, *hashBlockHeader);
  239. mpz_init(psieve->bnFixedFactor);
  240. mpz_mul(psieve->bnFixedFactor, *bnFixedMultiplier, *hashBlockHeader);
  241. }
  242. // Weave sieve for the next prime in table
  243. // Return values:
  244. // True - weaved another prime; nComposite - number of composites removed
  245. // False - sieve already completed
  246. static
  247. bool psieve_Weave(struct SieveOfEratosthenes *psieve)
  248. {
  249. unsigned nPrime = vPrimes[psieve->nPrimeSeq];
  250. if (psieve->nPrimeSeq >= PRIME_COUNT || nPrime >= psieve->nSieveSize)
  251. return false; // sieve has been completed
  252. if (mpz_fdiv_ui(psieve->bnFixedFactor, nPrime) == 0)
  253. {
  254. // Nothing in the sieve is divisible by this prime
  255. ++psieve->nPrimeSeq;
  256. return true;
  257. }
  258. // Find the modulo inverse of fixed factor
  259. mpz_t bnFixedInverse, p;
  260. mpz_init(bnFixedInverse);
  261. mpz_init_set_ui(p, nPrime);
  262. if (!mpz_invert(bnFixedInverse, psieve->bnFixedFactor, p))
  263. return error("CSieveOfEratosthenes::Weave(): BN_mod_inverse of fixed factor failed for prime #%u=%u", psieve->nPrimeSeq, nPrime);
  264. mpz_t bnTwo, bnTwoInverse;
  265. mpz_init_set_ui(bnTwo, 2);
  266. mpz_init(bnTwoInverse);
  267. if (!mpz_invert(bnTwoInverse, bnTwo, p))
  268. return error("CSieveOfEratosthenes::Weave(): BN_mod_inverse of 2 failed for prime #%u=%u", psieve->nPrimeSeq, nPrime);
  269. mpz_t mp;
  270. mpz_init(mp);
  271. // Weave the sieve for the prime
  272. unsigned int nChainLength = TargetGetLength(psieve->nBits);
  273. for (unsigned int nBiTwinSeq = 0; nBiTwinSeq < 2 * nChainLength; nBiTwinSeq++)
  274. {
  275. // Find the first number that's divisible by this prime
  276. int nDelta = ((nBiTwinSeq % 2 == 0) ? (-1) : 1);
  277. mpz_mul_ui(mp, bnFixedInverse, nPrime - nDelta);
  278. unsigned int nSolvedMultiplier = mpz_fdiv_ui(mp, nPrime);
  279. if (nBiTwinSeq % 2 == 1)
  280. mpz_mul(bnFixedInverse, bnFixedInverse, bnTwoInverse); // for next number in chain
  281. if (nBiTwinSeq < nChainLength)
  282. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  283. psieve->vfCompositeBiTwin[nVariableMultiplier] = true;
  284. if (((nBiTwinSeq & 1u) == 0))
  285. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  286. psieve->vfCompositeCunningham1[nVariableMultiplier] = true;
  287. if (((nBiTwinSeq & 1u) == 1u))
  288. for (unsigned int nVariableMultiplier = nSolvedMultiplier; nVariableMultiplier < psieve->nSieveSize; nVariableMultiplier += nPrime)
  289. psieve->vfCompositeCunningham2[nVariableMultiplier] = true;
  290. }
  291. ++psieve->nPrimeSeq;
  292. return true;
  293. }
  294. static
  295. bool psieve_GetNextCandidateMultiplier(struct SieveOfEratosthenes *psieve, unsigned int *pnVariableMultiplier)
  296. {
  297. while (true)
  298. {
  299. psieve->nCandidateMultiplier++;
  300. if (psieve->nCandidateMultiplier >= psieve->nSieveSize)
  301. {
  302. psieve->nCandidateMultiplier = 0;
  303. return false;
  304. }
  305. if (!psieve->vfCompositeCunningham1[psieve->nCandidateMultiplier] ||
  306. !psieve->vfCompositeCunningham2[psieve->nCandidateMultiplier] ||
  307. !psieve->vfCompositeBiTwin[psieve->nCandidateMultiplier])
  308. {
  309. *pnVariableMultiplier = psieve->nCandidateMultiplier;
  310. return true;
  311. }
  312. }
  313. }
  314. // Mine probable prime chain of form: n = h * p# +/- 1
  315. bool MineProbablePrimeChain(struct SieveOfEratosthenes *psieve, const uint8_t *header, mpz_t *hash, mpz_t *bnFixedMultiplier, bool *pfNewBlock, unsigned *pnTriedMultiplier, unsigned *pnProbableChainLength, unsigned *pnTests, unsigned *pnPrimesHit)
  316. {
  317. const uint32_t *pnbits = (void*)&header[72];
  318. *pnProbableChainLength = 0;
  319. *pnTests = 0;
  320. *pnPrimesHit = 0;
  321. if (*pfNewBlock && psieve->valid)
  322. {
  323. // Must rebuild the sieve
  324. psieve_reset(psieve);
  325. }
  326. *pfNewBlock = false;
  327. int64_t nStart, nCurrent; // microsecond timer
  328. if (!psieve->valid)
  329. {
  330. // Build sieve
  331. nStart = GetTimeMicros();
  332. psieve_init(psieve, nMaxSieveSize, *pnbits, hash, bnFixedMultiplier);
  333. while (psieve_Weave(psieve));
  334. // printf("MineProbablePrimeChain() : new sieve (%u/%u) ready in %uus\n", psieve_GetCandidateCount(psieve), nMaxSieveSize, (unsigned int) (GetTimeMicros() - nStart));
  335. }
  336. mpz_t bnChainOrigin;
  337. mpz_init(bnChainOrigin);
  338. nStart = GetTimeMicros();
  339. nCurrent = nStart;
  340. while (nCurrent - nStart < 10000 && nCurrent >= nStart)
  341. {
  342. ++*pnTests;
  343. if (!psieve_GetNextCandidateMultiplier(psieve, pnTriedMultiplier))
  344. {
  345. // power tests completed for the sieve
  346. psieve_reset(psieve);
  347. *pfNewBlock = true; // notify caller to change nonce
  348. return false;
  349. }
  350. mpz_mul(bnChainOrigin, *hash, *bnFixedMultiplier);
  351. mpz_mul_ui(bnChainOrigin, bnChainOrigin, *pnTriedMultiplier);
  352. unsigned int nChainLengthCunningham1 = 0;
  353. unsigned int nChainLengthCunningham2 = 0;
  354. unsigned int nChainLengthBiTwin = 0;
  355. if (ProbablePrimeChainTest(&bnChainOrigin, *pnbits, false, &nChainLengthCunningham1, &nChainLengthCunningham2, &nChainLengthBiTwin))
  356. {
  357. // TODO block.bnPrimeChainMultiplier = *bnFixedMultiplier * *pnTriedMultiplier;
  358. // printf("Probable prime chain found for block=%s!!\n Target: %s\n Length: (%s %s %s)\n", block.GetHash().GetHex().c_str(),
  359. // TargetToString(nbits).c_str(), TargetToString(nChainLengthCunningham1).c_str(), TargetToString(nChainLengthCunningham2).c_str(), TargetToString(nChainLengthBiTwin).c_str());
  360. *pnProbableChainLength = nChainLengthCunningham1;
  361. if (*pnProbableChainLength < nChainLengthCunningham2)
  362. *pnProbableChainLength = nChainLengthCunningham2;
  363. if (*pnProbableChainLength < nChainLengthBiTwin)
  364. *pnProbableChainLength = nChainLengthBiTwin;
  365. return true;
  366. }
  367. *pnProbableChainLength = nChainLengthCunningham1;
  368. if (*pnProbableChainLength < nChainLengthCunningham2)
  369. *pnProbableChainLength = nChainLengthCunningham2;
  370. if (*pnProbableChainLength < nChainLengthBiTwin)
  371. *pnProbableChainLength = nChainLengthBiTwin;
  372. if(TargetGetLength(*pnProbableChainLength) >= 1)
  373. ++*pnPrimesHit;
  374. nCurrent = GetTimeMicros();
  375. }
  376. return false; // stop as timed out
  377. }
  378. // Checks that the high bit is set, and low bit is clear (ie, divisible by 2)
  379. static
  380. bool check_ends(const uint8_t *hash)
  381. {
  382. return (hash[31] & 0x80) && !(hash[0] & 1);
  383. }
  384. static inline
  385. void set_mpz_to_hash(mpz_t *hash, const uint8_t *hashb)
  386. {
  387. mpz_import(*hash, 4, 1, 8, -1, 0, hashb);
  388. }
  389. unsigned int nPrimorialHashFactor = 7;
  390. int64_t nTimeExpected = 0; // time expected to prime chain (micro-second)
  391. int64_t nTimeExpectedPrev = 0; // time expected to prime chain last time
  392. bool fIncrementPrimorial = true; // increase or decrease primorial factor
  393. unsigned current_prime = 3; // index 3 is prime number 7
  394. int64_t nHPSTimerStart = 0;
  395. void prime(uint8_t *header)
  396. {
  397. uint32_t *nonce = (void*)(&header[76]);
  398. unsigned char hashb[32];
  399. mpz_t hash, bnPrimeMin;
  400. mpz_init(hash);
  401. mpz_init_set_ui(bnPrimeMin, 1);
  402. mpz_mul_2exp(bnPrimeMin, bnPrimeMin, 255);
  403. bool fNewBlock = true;
  404. unsigned int nTriedMultiplier = 0;
  405. struct SieveOfEratosthenes sieve = {
  406. .valid = false,
  407. };
  408. const unsigned nHashFactor = 210;
  409. // a valid header must hash to have the MSB set, and a multiple of nHashFactor
  410. while (true)
  411. {
  412. gen_hash(header, hashb, 80);
  413. if (check_ends(hashb))
  414. {
  415. set_mpz_to_hash(&hash, hashb);
  416. if (!mpz_fdiv_ui(hash, 105))
  417. break;
  418. }
  419. if (unlikely(*nonce == 0xffffffff))
  420. return;
  421. ++*nonce;
  422. }
  423. {
  424. char hex[9];
  425. bin2hex(hex, nonce, 4);
  426. fprintf(stderr, "Pass 1 found: %s\n", hex);
  427. }
  428. // primorial fixed multiplier
  429. mpz_t bnPrimorial;
  430. mpz_init(bnPrimorial);
  431. unsigned int nRoundTests = 0;
  432. unsigned int nRoundPrimesHit = 0;
  433. int64_t nPrimeTimerStart = GetTimeMicros();
  434. if (nTimeExpected > nTimeExpectedPrev)
  435. fIncrementPrimorial = !fIncrementPrimorial;
  436. nTimeExpectedPrev = nTimeExpected;
  437. // dynamic adjustment of primorial multiplier
  438. if (fIncrementPrimorial)
  439. {
  440. ++current_prime;
  441. if (current_prime >= PRIME_COUNT)
  442. quit(1, "primorial increment overflow");
  443. }
  444. else if (vPrimes[current_prime] > nPrimorialHashFactor)
  445. {
  446. if (!current_prime)
  447. quit(1, "primorial decrement overflow");
  448. --current_prime;
  449. }
  450. mpz_set(bnPrimorial, vPrimorials[current_prime]);
  451. while (true)
  452. {
  453. unsigned int nTests = 0;
  454. unsigned int nPrimesHit = 0;
  455. mpz_t bnMultiplierMin;
  456. // bnMultiplierMin = bnPrimeMin * nHashFactor / hash + 1
  457. mpz_init(bnMultiplierMin);
  458. mpz_mul_ui(bnMultiplierMin, bnPrimeMin, nHashFactor);
  459. mpz_fdiv_q(bnMultiplierMin, bnMultiplierMin, hash);
  460. mpz_add_ui(bnMultiplierMin, bnMultiplierMin, 1);
  461. while (mpz_cmp(bnPrimorial, bnMultiplierMin) < 0)
  462. {
  463. ++current_prime;
  464. if (current_prime >= PRIME_COUNT)
  465. quit(1, "primorial minimum overflow");
  466. mpz_set(bnPrimorial, vPrimorials[current_prime]);
  467. }
  468. mpz_t bnFixedMultiplier;
  469. mpz_init(bnFixedMultiplier);
  470. // bnFixedMultiplier = (bnPrimorial > nHashFactor) ? (bnPrimorial / nHashFactor) : 1
  471. if (mpz_cmp_ui(bnPrimorial, nHashFactor) > 0)
  472. {
  473. mpz_t bnHashFactor;
  474. mpz_init_set_ui(bnHashFactor, nHashFactor);
  475. mpz_fdiv_q(bnFixedMultiplier, bnPrimorial, bnHashFactor);
  476. }
  477. else
  478. mpz_set_ui(bnFixedMultiplier, 1);
  479. // mine for prime chain
  480. unsigned int nProbableChainLength;
  481. if (MineProbablePrimeChain(&sieve, header, &hash, &bnFixedMultiplier, &fNewBlock, &nTriedMultiplier, &nProbableChainLength, &nTests, &nPrimesHit))
  482. {
  483. // TODO CheckWork(pblock, *pwalletMain, reservekey);
  484. fprintf(stderr, "CHECK WORK\n");
  485. break;
  486. }
  487. nRoundTests += nTests;
  488. nRoundPrimesHit += nPrimesHit;
  489. // Meter primes/sec
  490. static int64_t nPrimeCounter;
  491. static int64_t nTestCounter;
  492. if (nHPSTimerStart == 0)
  493. {
  494. nHPSTimerStart = GetTimeMillis();
  495. nPrimeCounter = 0;
  496. nTestCounter = 0;
  497. }
  498. else
  499. {
  500. nPrimeCounter += nPrimesHit;
  501. nTestCounter += nTests;
  502. }
  503. #if 0
  504. if (GetTimeMillis() - nHPSTimerStart > 60000)
  505. {
  506. static CCriticalSection cs;
  507. {
  508. LOCK(cs);
  509. if (GetTimeMillis() - nHPSTimerStart > 60000)
  510. {
  511. double dPrimesPerMinute = 60000.0 * nPrimeCounter / (GetTimeMillis() - nHPSTimerStart);
  512. dPrimesPerSec = dPrimesPerMinute / 60.0;
  513. double dTestsPerMinute = 60000.0 * nTestCounter / (GetTimeMillis() - nHPSTimerStart);
  514. nHPSTimerStart = GetTimeMillis();
  515. nPrimeCounter = 0;
  516. nTestCounter = 0;
  517. static int64 nLogTime = 0;
  518. if (GetTime() - nLogTime > 60)
  519. {
  520. nLogTime = GetTime();
  521. printf("%s primemeter %9.0f prime/h %9.0f test/h\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nLogTime).c_str(), dPrimesPerMinute * 60.0, dTestsPerMinute * 60.0);
  522. }
  523. }
  524. }
  525. }
  526. #endif
  527. // Check for stop or if block needs to be rebuilt
  528. // TODO
  529. // boost::this_thread::interruption_point();
  530. // if (vNodes.empty())
  531. // break;
  532. // if (fNewBlock || pblock->nNonce >= 0xffff0000)
  533. // break;
  534. // if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  535. // break;
  536. // if (pindexPrev != pindexBest)
  537. // break;
  538. }
  539. // Primecoin: estimate time to block
  540. nTimeExpected = (GetTimeMicros() - nPrimeTimerStart) / max(1u, nRoundTests);
  541. nTimeExpected = nTimeExpected * max(1u, nRoundTests) / max(1u, nRoundPrimesHit);
  542. //TODO
  543. // for (unsigned int n = 1; n < TargetGetLength(pblock->nBits); n++)
  544. // nTimeExpected = nTimeExpected * max(1u, nRoundTests) * 3 / max(1u, nRoundPrimesHit);
  545. printf("PrimecoinMiner() : Round primorial=%u tests=%u primes=%u expected=%us\n", vPrimes[current_prime], nRoundTests, nRoundPrimesHit, (unsigned int)(nTimeExpected/1000000));
  546. }
  547. void main()
  548. {
  549. GeneratePrimeTable();
  550. unsigned char array[80] = {
  551. 0x02, 0x00, 0x00, 0x00,
  552. 0x06, 0x21, 0x15, 0xa0, 0xb9, 0x7d, 0x83, 0x26, 0xff, 0xad, 0x2b, 0x82, 0x46, 0x25, 0x4e, 0x67,
  553. 0xf9, 0x3a, 0xfb, 0x6a, 0xf5, 0xa2, 0x78, 0x80, 0x13, 0x53, 0xc7, 0x4d, 0xba, 0x17, 0x3d, 0x96,
  554. 0xee, 0x52, 0x24, 0xd0, 0xf6, 0xcd, 0x53, 0x50, 0x8c, 0x4b, 0x63, 0x39, 0x1d, 0x28, 0x86, 0x9d,
  555. 0x35, 0x21, 0xeb, 0x8d, 0x43, 0xbe, 0x82, 0xcf, 0x58, 0x48, 0x1d, 0xa0, 0xd0, 0xe4, 0x13, 0x72,
  556. 0x30, 0xb3, 0xd9, 0x51,
  557. 0x00, 0x00, 0x00, 0x07,
  558. 0x1d, 0x00, 0x00, 0x00
  559. };
  560. prime(array);
  561. }