Browse Source

initial commit

master
mortie 5 years ago
commit
9d398d0665
7 changed files with 984 additions and 0 deletions
  1. 1
    0
      .gitignore
  2. 37
    0
      js/asicconn.js
  3. 88
    0
      js/miner.js
  4. 85
    0
      js/rpcconn.js
  5. 736
    0
      package-lock.json
  6. 14
    0
      package.json
  7. 23
    0
      script.js

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
node_modules

+ 37
- 0
js/asicconn.js View File

@@ -0,0 +1,37 @@
var SerialPort = require("serialport");

class ASICConn {
constructor(dev, baud) {
this.ready = false;
this.error = null;

this._onready = [];

this._port = new SerialPort(dev, {
baudRate: baud
});

this._port.on("error", msg => {
this.error = msg;
this._onready.forEach(x => x());
});
this._port.on("open", () => {
this.ready = true;
this._onready.forEach(x => x());
});
this._port.on("data", d => {
console.log("From "+dev+": "+d);
});
}

wait() {
return new Promise((resolve, reject) => {
if (this.ready)
return resolve();

this._onready.push(resolve);
});
}
}

module.exports = ASICConn;

+ 88
- 0
js/miner.js View File

@@ -0,0 +1,88 @@
var RPCConn = require("./rpcconn");
var ASICConn = require("./asicconn");

class Miner {
constructor(ip, port, dev, baud) {
this.name = dev
this.work = null;
this.nextDifficulty = 1;
this.exnounce1 = null;
this.exnounce2_len = null;

this.asic = new ASICConn(dev, baud);
this.rpc = new RPCConn(ip, port);
}

log(...msgs) {
process.stdout.write(this.name+": ");
console.log(msgs);
}

async connect() {
await this.asic.wait();
await this.rpc.wait();

if (this.asic.error)
throw this.asic.error;

this.rpc.on("mining.notify", 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.notify(work);
});
this.rpc.on("mining.set_difficulty", params => {
this.log("difficulty", params);
this.difficulty(params[0]);
});

var sub = await this.rpc.call("mining.subscribe");
this.exnounce1 = sub[1];
this.exnounce2_len = sub[2];
}

async auth(user, pass) {
var success = await this.rpc.call("mining.authorize", user, pass);
if (!success)
throw new Error("Incorrect username/password.");
console.log("Authenticated "+user+".");
}

notify(work) {
if (this.exnounce1 == null)
return console.log("Ignoring work because extranounce is null.");

this.log("Notification");
this.log(work);
this.work = work;
this.log(
"Using extranounce1 '"+this.exnounce1+
"', and exnounce2 length "+this.exnounce2_len);
}

difficulty(diff) {
this.nextDifficulty = diff;
}

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 = Miner;

+ 85
- 0
js/rpcconn.js View File

@@ -0,0 +1,85 @@
var net = require("net");

class RPCConn {
constructor(ip, port) {
this.ready = false;

this._callbacks = {};
this._onready = [];
this._listeners = {};

this._id = 1;
this.sock = new net.Socket();
this.sock.connect(port, ip, () => {
console.log("Connected to RPC server "+ip+":"+port+".");
this.ready = true;
this._onready.forEach(x => x());
});

var onjson = json => {
var obj = JSON.parse(json);

if (obj.id == null) {
var listeners = this._listeners[obj.method];

if (listeners)
listeners.forEach(l => l(obj.params));
if (!listeners || listeners.length === 0)
console.log("Received method '"+obj.method+"', but no listeners.");

return;
}

var cb = this._callbacks[obj.id];
if (!cb)
return console.log("Warning: received unknown ID "+obj.id);

cb(obj.error, obj.result);
}

var currdata = "";
this.sock.on("data", d => {
var s = d.toString();
currdata += d;
if (s.indexOf("\n") !== -1) {
currdata.split("\n").filter(l => l !== "").forEach(onjson);
currdata = "";
}
});
}

wait() {
return new Promise((resolve, reject) => {
if (this.ready)
return resolve();

this._onready.push(resolve);
});
}


call(name, ...params) {
return new Promise((resolve, reject) => {
var json = JSON.stringify({
id: this._id,
method: name,
params: params
});
this._callbacks[this._id] = (err, res) => {
if (err) reject(err);
else resolve(res);
}

console.log("Sending '"+json+"'");
this.sock.write(json+"\n");
this._id += 1;
});
}

on(name, fn) {
this._listeners[name] = this._listeners[name] || [];
this._listeners[name].push(fn);
}
}

module.exports = RPCConn;

+ 736
- 0
package-lock.json View File

@@ -0,0 +1,736 @@
{
"name": "stratum-test",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"bindings": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
},
"commander": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
},
"nan": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY="
},
"promirepl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/promirepl/-/promirepl-1.0.1.tgz",
"integrity": "sha1-KVGq66K/P+InT/Y6FtlMBMpghy4="
},
"serialport": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/serialport/-/serialport-5.0.0.tgz",
"integrity": "sha512-xOCTlKQDyzQR1C3eR45n7ogZEJojpraH0WSqLw7q47lJrJXXLBUY1AjDYhdJb+SiT8dHrk8h8MJadQG7L5mIRw==",
"requires": {
"bindings": "1.3.0",
"commander": "2.11.0",
"debug": "2.6.8",
"nan": "2.7.0",
"node-pre-gyp": "0.6.36",
"promirepl": "1.0.1",
"safe-buffer": "5.1.1"
},
"dependencies": {
"abbrev": {
"version": "1.1.0",
"bundled": true
},
"ajv": {
"version": "4.11.8",
"bundled": true,
"requires": {
"co": "4.6.0",
"json-stable-stringify": "1.0.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true
},
"aproba": {
"version": "1.1.2",
"bundled": true
},
"are-we-there-yet": {
"version": "1.1.4",
"bundled": true,
"requires": {
"delegates": "1.0.0",
"readable-stream": "2.3.3"
}
},
"asn1": {
"version": "0.2.3",
"bundled": true
},
"assert-plus": {
"version": "0.2.0",
"bundled": true
},
"asynckit": {
"version": "0.4.0",
"bundled": true
},
"aws-sign2": {
"version": "0.6.0",
"bundled": true
},
"aws4": {
"version": "1.6.0",
"bundled": true
},
"balanced-match": {
"version": "1.0.0",
"bundled": true
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"bundled": true,
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
}
},
"block-stream": {
"version": "0.0.9",
"bundled": true,
"requires": {
"inherits": "2.0.3"
}
},
"boom": {
"version": "2.10.1",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"brace-expansion": {
"version": "1.1.8",
"bundled": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
}
},
"caseless": {
"version": "0.12.0",
"bundled": true
},
"co": {
"version": "4.6.0",
"bundled": true
},
"code-point-at": {
"version": "1.1.0",
"bundled": true
},
"combined-stream": {
"version": "1.0.5",
"bundled": true,
"requires": {
"delayed-stream": "1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
"bundled": true
},
"cryptiles": {
"version": "2.0.5",
"bundled": true,
"requires": {
"boom": "2.10.1"
}
},
"dashdash": {
"version": "1.14.1",
"bundled": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true
}
}
},
"debug": {
"version": "2.6.8",
"bundled": true,
"requires": {
"ms": "2.0.0"
}
},
"deep-extend": {
"version": "0.4.2",
"bundled": true
},
"delayed-stream": {
"version": "1.0.0",
"bundled": true
},
"delegates": {
"version": "1.0.0",
"bundled": true
},
"ecc-jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"extend": {
"version": "3.0.1",
"bundled": true
},
"extsprintf": {
"version": "1.0.2",
"bundled": true
},
"forever-agent": {
"version": "0.6.1",
"bundled": true
},
"form-data": {
"version": "2.1.4",
"bundled": true,
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.16"
}
},
"fs.realpath": {
"version": "1.0.0",
"bundled": true
},
"fstream": {
"version": "1.0.11",
"bundled": true,
"requires": {
"graceful-fs": "4.1.11",
"inherits": "2.0.3",
"mkdirp": "0.5.1",
"rimraf": "2.6.1"
}
},
"fstream-ignore": {
"version": "1.0.5",
"bundled": true,
"requires": {
"fstream": "1.0.11",
"inherits": "2.0.3",
"minimatch": "3.0.4"
}
},
"gauge": {
"version": "2.7.4",
"bundled": true,
"requires": {
"aproba": "1.1.2",
"console-control-strings": "1.1.0",
"has-unicode": "2.0.1",
"object-assign": "4.1.1",
"signal-exit": "3.0.2",
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wide-align": "1.1.2"
}
},
"getpass": {
"version": "0.1.7",
"bundled": true,
"requires": {
"assert-plus": "1.0.0"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true
}
}
},
"glob": {
"version": "7.1.2",
"bundled": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
},
"graceful-fs": {
"version": "4.1.11",
"bundled": true
},
"har-schema": {
"version": "1.0.5",
"bundled": true
},
"har-validator": {
"version": "4.2.1",
"bundled": true,
"requires": {
"ajv": "4.11.8",
"har-schema": "1.0.5"
}
},
"has-unicode": {
"version": "2.0.1",
"bundled": true
},
"hawk": {
"version": "3.1.3",
"bundled": true,
"requires": {
"boom": "2.10.1",
"cryptiles": "2.0.5",
"hoek": "2.16.3",
"sntp": "1.0.9"
}
},
"hoek": {
"version": "2.16.3",
"bundled": true
},
"http-signature": {
"version": "1.1.1",
"bundled": true,
"requires": {
"assert-plus": "0.2.0",
"jsprim": "1.4.0",
"sshpk": "1.13.1"
}
},
"inflight": {
"version": "1.0.6",
"bundled": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
}
},
"inherits": {
"version": "2.0.3",
"bundled": true
},
"ini": {
"version": "1.3.4",
"bundled": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"requires": {
"number-is-nan": "1.0.1"
}
},
"is-typedarray": {
"version": "1.0.0",
"bundled": true
},
"isarray": {
"version": "1.0.0",
"bundled": true
},
"isstream": {
"version": "0.1.2",
"bundled": true
},
"jsbn": {
"version": "0.1.1",
"bundled": true,
"optional": true
},
"json-schema": {
"version": "0.2.3",
"bundled": true
},
"json-stable-stringify": {
"version": "1.0.1",
"bundled": true,
"requires": {
"jsonify": "0.0.0"
}
},
"json-stringify-safe": {
"version": "5.0.1",
"bundled": true
},
"jsonify": {
"version": "0.0.0",
"bundled": true
},
"jsprim": {
"version": "1.4.0",
"bundled": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.0.2",
"json-schema": "0.2.3",
"verror": "1.3.6"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true
}
}
},
"mime-db": {
"version": "1.29.0",
"bundled": true
},
"mime-types": {
"version": "2.1.16",
"bundled": true,
"requires": {
"mime-db": "1.29.0"
}
},
"minimatch": {
"version": "3.0.4",
"bundled": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true
},
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"requires": {
"minimist": "0.0.8"
}
},
"ms": {
"version": "2.0.0",
"bundled": true
},
"node-pre-gyp": {
"version": "0.6.36",
"bundled": true,
"requires": {
"mkdirp": "0.5.1",
"nopt": "4.0.1",
"npmlog": "4.1.2",
"rc": "1.2.1",
"request": "2.81.0",
"rimraf": "2.6.1",
"semver": "5.4.1",
"tar": "2.2.1",
"tar-pack": "3.4.0"
}
},
"nopt": {
"version": "4.0.1",
"bundled": true,
"requires": {
"abbrev": "1.1.0",
"osenv": "0.1.4"
}
},
"npmlog": {
"version": "4.1.2",
"bundled": true,
"requires": {
"are-we-there-yet": "1.1.4",
"console-control-strings": "1.1.0",
"gauge": "2.7.4",
"set-blocking": "2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true
},
"oauth-sign": {
"version": "0.8.2",
"bundled": true
},
"object-assign": {
"version": "4.1.1",
"bundled": true
},
"once": {
"version": "1.4.0",
"bundled": true,
"requires": {
"wrappy": "1.0.2"
}
},
"os-homedir": {
"version": "1.0.2",
"bundled": true
},
"os-tmpdir": {
"version": "1.0.2",
"bundled": true
},
"osenv": {
"version": "0.1.4",
"bundled": true,
"requires": {
"os-homedir": "1.0.2",
"os-tmpdir": "1.0.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true
},
"performance-now": {
"version": "0.2.0",
"bundled": true
},
"process-nextick-args": {
"version": "1.0.7",
"bundled": true
},
"punycode": {
"version": "1.4.1",
"bundled": true
},
"qs": {
"version": "6.4.0",
"bundled": true
},
"rc": {
"version": "1.2.1",
"bundled": true,
"requires": {
"deep-extend": "0.4.2",
"ini": "1.3.4",
"minimist": "1.2.0",
"strip-json-comments": "2.0.1"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"bundled": true
}
}
},
"readable-stream": {
"version": "2.3.3",
"bundled": true,
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"request": {
"version": "2.81.0",
"bundled": true,
"requires": {
"aws-sign2": "0.6.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.1.4",
"har-validator": "4.2.1",
"hawk": "3.1.3",
"http-signature": "1.1.1",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.16",
"oauth-sign": "0.8.2",
"performance-now": "0.2.0",
"qs": "6.4.0",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.2",
"tunnel-agent": "0.6.0",
"uuid": "3.1.0"
}
},
"rimraf": {
"version": "2.6.1",
"bundled": true,
"requires": {
"glob": "7.1.2"
}
},
"safe-buffer": {
"version": "5.1.1",
"bundled": true
},
"semver": {
"version": "5.4.1",
"bundled": true
},
"set-blocking": {
"version": "2.0.0",
"bundled": true
},
"signal-exit": {
"version": "3.0.2",
"bundled": true
},
"sntp": {
"version": "1.0.9",
"bundled": true,
"requires": {
"hoek": "2.16.3"
}
},
"sshpk": {
"version": "1.13.1",
"bundled": true,
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.1",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.1",
"getpass": "0.1.7",
"jsbn": "0.1.1",
"tweetnacl": "0.14.5"
},
"dependencies": {
"assert-plus": {
"version": "1.0.0",
"bundled": true
}
}
},
"string_decoder": {
"version": "1.0.3",
"bundled": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"requires": {
"code-point-at": "1.1.0",
"is-fullwidth-code-point": "1.0.0",
"strip-ansi": "3.0.1"
}
},
"stringstream": {
"version": "0.0.5",
"bundled": true
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"strip-json-comments": {
"version": "2.0.1",
"bundled": true
},
"tar": {
"version": "2.2.1",
"bundled": true,
"requires": {
"block-stream": "0.0.9",
"fstream": "1.0.11",
"inherits": "2.0.3"
}
},
"tar-pack": {
"version": "3.4.0",
"bundled": true,
"requires": {
"debug": "2.6.8",
"fstream": "1.0.11",
"fstream-ignore": "1.0.5",
"once": "1.4.0",
"readable-stream": "2.3.3",
"rimraf": "2.6.1",
"tar": "2.2.1",
"uid-number": "0.0.6"
}
},
"tough-cookie": {
"version": "2.3.2",
"bundled": true,
"requires": {
"punycode": "1.4.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"bundled": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"bundled": true,
"optional": true
},
"uid-number": {
"version": "0.0.6",
"bundled": true
},
"util-deprecate": {
"version": "1.0.2",
"bundled": true
},
"uuid": {
"version": "3.1.0",
"bundled": true
},
"verror": {
"version": "1.3.6",
"bundled": true,
"requires": {
"extsprintf": "1.0.2"
}
},
"wide-align": {
"version": "1.1.2",
"bundled": true,
"requires": {
"string-width": "1.0.2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true
}
}
}
}
}

+ 14
- 0
package.json View File

@@ -0,0 +1,14 @@
{
"name": "stratum-test",
"version": "1.0.0",
"description": "",
"main": "thing.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"serialport": "^5.0.0"
}
}

+ 23
- 0
script.js View File

@@ -0,0 +1,23 @@
#!/usr/bin/env node

var dns = require("dns");
var Miner = require("./js/miner");

var domain = "stratum.slushpool.com"
var port = 3333;

async function main() {
dns.lookup(domain, async (err, ip) => {
if (err) throw err;

var m = new Miner(ip, port, "/dev/ttyACM0", 115200);
try {
await m.connect();
await m.auth("mort96.worker1", "test");
} catch (err) {
console.log(err);
process.exit(1);
}
});
}
main();

Loading…
Cancel
Save