work2d.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright 2013-2014 Luke Dashjr
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation; either version 3 of the License, or (at your option)
  7. * any later version. See COPYING for more details.
  8. */
  9. #include "config.h"
  10. #include <limits.h>
  11. #include <stdbool.h>
  12. #include <stdint.h>
  13. #include <string.h>
  14. #include "miner.h"
  15. #include "util.h"
  16. #include "work2d.h"
  17. #define MAX_DIVISIONS WORK2D_MAX_DIVISIONS
  18. static bool work2d_reserved[MAX_DIVISIONS + 1] = { true };
  19. int work2d_xnonce1sz;
  20. int work2d_xnonce2sz;
  21. void work2d_init()
  22. {
  23. RUNONCE();
  24. for (uint64_t n = MAX_DIVISIONS; n; n >>= 8)
  25. ++work2d_xnonce1sz;
  26. work2d_xnonce2sz = 2;
  27. }
  28. bool reserve_work2d_(uint32_t * const xnonce1_p)
  29. {
  30. uint32_t xnonce1;
  31. for (xnonce1 = MAX_DIVISIONS; work2d_reserved[xnonce1]; --xnonce1)
  32. if (!xnonce1)
  33. return false;
  34. work2d_reserved[xnonce1] = true;
  35. *xnonce1_p = htole32(xnonce1);
  36. return true;
  37. }
  38. void release_work2d_(uint32_t xnonce1)
  39. {
  40. xnonce1 = le32toh(xnonce1);
  41. work2d_reserved[xnonce1] = false;
  42. }
  43. int work2d_pad_xnonce_size(const struct stratum_work * const swork)
  44. {
  45. return swork->n2size - work2d_xnonce1sz - work2d_xnonce2sz;
  46. }
  47. void *work2d_pad_xnonce(void * const buf_, const struct stratum_work * const swork, const bool hex)
  48. {
  49. uint8_t * const buf = buf_;
  50. int pad = work2d_pad_xnonce_size(swork);
  51. if (pad < 0)
  52. return NULL;
  53. if (hex)
  54. {
  55. pad *= 2;
  56. memset(buf, 'b', pad);
  57. }
  58. else
  59. memset(buf, '\xbb', pad);
  60. return &buf[pad];
  61. }
  62. static void work2d_gen_dummy_work_prepare(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared)
  63. {
  64. *work = (struct work){
  65. .pool = swork->pool,
  66. .work_restart_id = swork->work_restart_id,
  67. .tv_staged = *tvp_prepared,
  68. };
  69. }
  70. void work2d_gen_dummy_work(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared, const void * const xnonce2, const uint32_t xnonce1)
  71. {
  72. uint8_t *p, *s;
  73. work2d_gen_dummy_work_prepare(work, swork, tvp_prepared);
  74. bytes_resize(&work->nonce2, swork->n2size);
  75. s = bytes_buf(&work->nonce2);
  76. p = &s[swork->n2size - work2d_xnonce2sz];
  77. if (xnonce2)
  78. memcpy(p, xnonce2, work2d_xnonce2sz);
  79. #ifndef __OPTIMIZE__
  80. else
  81. memset(p, '\0', work2d_xnonce2sz);
  82. #endif
  83. p -= work2d_xnonce1sz;
  84. memcpy(p, &xnonce1, work2d_xnonce1sz);
  85. work2d_pad_xnonce(s, swork, false);
  86. gen_stratum_work2(work, swork);
  87. }
  88. void work2d_gen_dummy_work_for_stale_check(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared, cglock_t * const data_lock_p)
  89. {
  90. work2d_gen_dummy_work_prepare(work, swork, tvp_prepared);
  91. gen_stratum_work3(work, swork, data_lock_p);
  92. }
  93. bool work2d_submit_nonce(struct thr_info * const thr, struct stratum_work * const swork, const struct timeval * const tvp_prepared, const void * const xnonce2, const uint32_t xnonce1, const uint32_t nonce, const uint32_t ntime, bool * const out_is_stale, const float nonce_diff)
  94. {
  95. struct work _work, *work;
  96. bool rv;
  97. // Generate dummy work
  98. work = &_work;
  99. work2d_gen_dummy_work(work, swork, tvp_prepared, xnonce2, xnonce1);
  100. *(uint32_t *)&work->data[68] = htobe32(ntime);
  101. work->nonce_diff = nonce_diff;
  102. work->rolltime = INT_MAX; // FIXME
  103. // Check if it's stale, if desired
  104. if (out_is_stale)
  105. *out_is_stale = stale_work(work, true);
  106. // Submit nonce
  107. rv = submit_nonce(thr, work, nonce);
  108. clean_work(work);
  109. return rv;
  110. }