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