Source: mining/common.js

  1. /*!
  2. * common.js - mining utils
  3. * Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
  4. * https://github.com/bcoin-org/bcoin
  5. */
  6. 'use strict';
  7. const assert = require('bsert');
  8. const consensus = require('../protocol/consensus');
  9. const BN = require('bcrypto/lib/bn.js');
  10. /**
  11. * @exports mining/common
  12. */
  13. const common = exports;
  14. /*
  15. * Constants
  16. */
  17. const DIFF = 0x00000000ffff0000000000000000000000000000000000000000000000000000;
  18. const B192 = 0x1000000000000000000000000000000000000000000000000;
  19. const B128 = 0x100000000000000000000000000000000;
  20. const B64 = 0x10000000000000000;
  21. const B0 = 0x1;
  22. /**
  23. * Swap 32 bit endianness of uint256.
  24. * @param {Buffer} data
  25. * @returns {Buffer}
  26. */
  27. common.swap32 = function swap32(data) {
  28. for (let i = 0; i < data.length; i += 4) {
  29. const field = data.readUInt32LE(i, true);
  30. data.writeUInt32BE(field, i, true);
  31. }
  32. return data;
  33. };
  34. /**
  35. * Compare two uint256le's.
  36. * @param {Buffer} a
  37. * @param {Buffer} b
  38. * @returns {Number}
  39. */
  40. common.rcmp = function rcmp(a, b) {
  41. assert(a.length === b.length);
  42. for (let i = a.length - 1; i >= 0; i--) {
  43. if (a[i] < b[i])
  44. return -1;
  45. if (a[i] > b[i])
  46. return 1;
  47. }
  48. return 0;
  49. };
  50. /**
  51. * Convert a uint256le to a double.
  52. * @param {Buffer} target
  53. * @returns {Number}
  54. */
  55. common.double256 = function double256(target) {
  56. let n = 0;
  57. let hi, lo;
  58. assert(target.length === 32);
  59. hi = target.readUInt32LE(28, true);
  60. lo = target.readUInt32LE(24, true);
  61. n += (hi * 0x100000000 + lo) * B192;
  62. hi = target.readUInt32LE(20, true);
  63. lo = target.readUInt32LE(16, true);
  64. n += (hi * 0x100000000 + lo) * B128;
  65. hi = target.readUInt32LE(12, true);
  66. lo = target.readUInt32LE(8, true);
  67. n += (hi * 0x100000000 + lo) * B64;
  68. hi = target.readUInt32LE(4, true);
  69. lo = target.readUInt32LE(0, true);
  70. n += (hi * 0x100000000 + lo) * B0;
  71. return n;
  72. };
  73. /**
  74. * Calculate mining difficulty
  75. * from little-endian target.
  76. * @param {Buffer} target
  77. * @returns {Number}
  78. */
  79. common.getDifficulty = function getDifficulty(target) {
  80. const d = DIFF;
  81. const n = common.double256(target);
  82. if (n === 0)
  83. return d;
  84. return Math.floor(d / n);
  85. };
  86. /**
  87. * Get target from bits as a uint256le.
  88. * @param {Number} bits
  89. * @returns {Buffer}
  90. */
  91. common.getTarget = function getTarget(bits) {
  92. const target = consensus.fromCompact(bits);
  93. if (target.isNeg())
  94. throw new Error('Target is negative.');
  95. if (target.isZero())
  96. throw new Error('Target is zero.');
  97. return target.toArrayLike(Buffer, 'le', 32);
  98. };
  99. /**
  100. * Get bits from target.
  101. * @param {Buffer} data
  102. * @returns {Buffer}
  103. */
  104. common.getBits = function getBits(data) {
  105. const target = new BN(data, 'le');
  106. if (target.isZero())
  107. throw new Error('Target is zero.');
  108. return consensus.toCompact(target);
  109. };