-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblock.reference.js
executable file
·121 lines (99 loc) · 3.47 KB
/
block.reference.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
'use strict';
const xmr = require('./xmr.js');
const logger = (s) => console.log(s)
// Value is 16^64 or 2^256
const hex256 = BigInt('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')
const INVALID = 0;
const LOW_SCORE = 1;
const VALID = 2;
const WINNER = 3;
const BlockReference = {
// Protobuf handler (unfortunately does not seem its easy to avoid callbacks)
processBlock: (call, callback) => {
// Check protobuf params
const pblock = call.request;
const result = BlockReference.checkDifficulty(
pblock.local_diff,
pblock.global_diff,
pblock.hex_result
);
return callback(null,
{
block_status : result,
});
},
constructJob: (call, callback) => {
// Check protobuf params
const input = call.request.jobstub;
return callback(null, {
jobstub: input
});
},
// Checks if block sent by miner corresponds to the job they were assigned
verifyBlock: (blob, nonce, extraNonce, seed_hash, result) => {
try {
let block = BlockReference.buildBlock(blob, nonce, extraNonce);
block = BlockReference.convertBlock(block);
block = BlockReference.hashBlock(block, seed_hash);
return block.toString('hex') == result;
} catch (err) {
logger(err);
return false;
}
},
buildBlock: (blob, nonce, extraNonce) => {
let block = Buffer.from(blob, "hex");
// Value of 8 is given because our default reserve_offset is set to 8
block.writeUInt32BE(extraNonce, 8);
const NonceBuffer = Buffer.from(nonce, 'hex');
return xmr.construct_block_blob(block, NonceBuffer);
},
convertBlock: (constructedBlock) => xmr.convert_blob(constructedBlock),
hashBlock: (block, seed_hash) => xmr.randomx(block, Buffer.from(seed_hash, 'hex')),
checkDifficulty: (localDiff, globalDiff, block) => {
let rawBlock = Buffer.from(block, 'hex');
rawBlock = Array.prototype.slice.call(rawBlock, 0).reverse();
let hexBlock = Buffer.from(rawBlock).toString('hex');
if(!hexBlock.trim()) return INVALID;
const blockInt = BigInt(`0x${hexBlock}`)
let hashDiff = hex256 / blockInt;
hashDiff = BigInt(hashDiff)
globalDiff = BigInt(globalDiff);
localDiff = BigInt(localDiff);
if (hashDiff >= globalDiff) {
// We won the block reward!
// Submit to monero node
return WINNER;
}
if (hashDiff >= localDiff) {
// Grant share to miner
return VALID;
}
// Block does not match difficulty requirements: low difficulty share
return LOW_SCORE;
},
// Checks if block sent by miner corresponds to the job they were assigned
verifyBlockNonProto: (minerData, job) => {
try {
let block = BlockReference.buildBlock(job.blob, minerData.nonce, job.extraNonce);
block = BlockReference.convertBlock(block);
block = BlockReference.hashBlock(block, job.seed_hash);
return block.toString('hex') == minerData.result;
} catch (err) {
logger(err);
return false;
}
},
// Used when our nonce is represented as an integer value
buildIntNonce: (blob, nonce) => {
let block = Buffer.from(blob, "hex");
const buf = Buffer.allocUnsafe(4);
buf.writeUInt32LE(nonce);
const NonceBuffer = buf;
return xmr.construct_block_blob(block, NonceBuffer);
},
// For fallback:
// new Buffer(minerData.nonce, 'hex').copy(block, 39);
// Writing the nonce in a specific position if util does not work in testing
};
module.exports = BlockReference;