var RPCConn = require("./rpcconn"); class StratumClient { constructor(ip, port, miner) { this.name = ip+":"+port; this.queue = []; this.working = false; this.nounceReady = false; this.difficultyReady = false; this.miner = miner; this.rpc = new RPCConn(ip, port); } log(...msgs) { process.stdout.write(this.name+": "); console.log.apply(console, msgs); } async startWork() { if (this.working) return; if (this.queue.length === 0) return; var work = this.queue.shift(); this.log("Starting work", work.id); this.working = true; var res; try { res = await this.miner.startWork(work); } catch (err) { console.trace(err); return; } finally { this.working = false; this.startWork(); } this.log("Work done,", res.toString("hex")); } async connect() { await this.rpc.wait(); await this.miner.wait(); this.rpc.on("mining.notify", async params => { var work = { id: params[0], prevHash: params[1], coinb1: params[2], coinb2: params[3], merkleBranch: params[4], version: params[5], nBits: params[6], nTime: params[7], cleanJobs: params[8], }; this.log("Got work", work.id); this.queue.push(work); if (this.difficultyReady && this.nounceReady) this.startWork(); }); this.rpc.on("mining.set_difficulty", params => { this.log("Got difficulty", params[0]); this.miner.setDifficulty(params[0]); if (this.difficultyReady) return; this.difficultyReady = true; if (this.nounceReady) this.startWork(); }); var sub = await this.rpc.call("mining.subscribe"); this.log("Got nounce", sub[1]); this.miner.setNounce(sub[1], sub[2]); this.nounceReady = true; if (this.difficultyReady) this.startWork(); } async auth(user, pass) { var success = await this.rpc.call("mining.authorize", user, pass); if (!success) throw new Error("Incorrect username/password."); this.log("Authenticated "+user+"."); } writePayload() { var rdlen = 95 - 63; var rdata = Buffer.alloc(rdlen); for (var i = 0; i < rdlen; ++i) rdata[i] = this._block[94 - i]; var rmlen = 64; var rmid = Buffer.alloc(rmlen); for (var i = 0; i < rmlen; ++i) rmid[i] = this._midstate[rmlen - i - 1]; var payload = Buffer.concat([rmid, rdata]); this.log("Writing '"+payload.toString("hex")+"'"); this._port.write(payload); } } module.exports = StratumClient;