var spawn = require("child_process").spawn; function hps(n) { var suffix = "Hash/s"; if (n > 1000000) { n = n / 1000000; suffix ="M"+suffix; } else if (n > 1000) { n = n / 1000; suffix = "k"+suffix; } return (n.toFixed(2))+" "+suffix; } function mineProc(cb1, cb2, merk, dif, en1, en2, cnt) { var obj = { coinb1: cb1, coinb2: cb2, merkleBranch: merk, difficulty: dif, exnounce1: en1, exnounce2: en2, iters: cnt }; var child = spawn( "node", [ __dirname+"/mining-process.js", JSON.stringify(obj) ]); child.output = ""; child.hps = 0; child.stderr.on("data", d => process.stderr.write(d)); child.stdout.on("data", d => { var s = d.toString(); if (s[0] === "o") child.output = s.substr(1); else if (s[0] === "h") child.hps = parseInt(s.substr(1)); else console.error("Warning: Unexpected child output,", s); }); return child; } function mine( coinb1, coinb2, merkleBranch, difficulty, exnounce1, exnounce2_len) { var cores = 4; var max = Math.pow(2, exnounce2_len * 8) - 2; var parts = Math.ceil(max / cores); return new Promise((resolve, reject) => { var childs = []; var childsLeft = cores; var inter = null; function rej(hash) { clearInterval(inter); resolve(hash); } for (var i = 0; i < cores; ++i) { var num = parts * i; if (num + parts > max) max - parts; var buf = Buffer.alloc(exnounce2_len, '\0'); buf.writeUInt32BE(num); var exnounce2 = buf.toString("hex"); var child = mineProc( coinb1, coinb2, merkleBranch, difficulty, exnounce1, exnounce2, parts); var obj = { coinb1, coinb2, merkleBranch, difficulty, exnounce1, exnounce2_len }; childs[i] = child; } childs.forEach(child => { child.on("exit", code => { console.error("Child exited with code", code); if (code === 0) { childsLeft -= 1; childs.forEach(x => x !== child && x.kill()); rej(child.output.trim()); } else { childsLeft -= 1; if (childsLeft <= 0) rej(false); } }); }); inter = setInterval(() => { var sum = 0; childs.forEach(c => sum += c.hps); console.log(hps(sum)); }, 2000); }); } class CPUMiner { constructor() { this.work = null; this.difficulty = 1; this.exnounce1 = null; this.exnounce2_len = null; } async startWork(work) { console.log("Starting work", work.id); if (this.exnounce1 == null) { console.log("Ignoring work because extranounce is null."); return false; } this.work = work; return await mine( this.work.coinb1, this.work.coinb2, this.work.berkleBranch, this.difficulty, this.exnounce1, this.exnounce2_len); } setDifficulty(difficulty) { this.difficulty = difficulty; } setNounce(en1, en2_len) { this.exnounce1 = en1; this.exnounce2_len = en2_len; } async wait() { } } module.exports = CPUMiner;