intchains_ibctminer
Version:
```js const IntMiner = require('./src'); const Debug = require('./src/log')(); const fs = require('fs'); const COMP = '[SIPC]';
221 lines (200 loc) • 6.32 kB
JavaScript
const EventEmitter = require('events');
const stratum = require('./stratum');
const Debug = require('../log')();
const uuid = require("uuid");
const COMP = '[intStratum]';
class intStratum extends EventEmitter {
constructor({}) {
super();
var _this = this;
_this.client = null;
_this.online = false;
_this.auth = false;
_this.socket = null;
_this.sendQueue = [];
_this.lastRecvPacket = null;
_this.lastSendPacket = null;
_this.id = uuid.v4();
return _this;
}
stratumAuthorize(id, user, pass) {
return this.socket.stratumSend({
'method': 'mining.authorize',
'id': id,
'params': [user, pass]
}, true);
}
stratumSubmit(id, submitData) {
this.socket.setLastActivity();
return this.socket.stratumSend({
'method': 'mining.submit',
'id': id,
'params': submitData
});
}
setupLoginPacket(data, job) {
// for setup for connect.js
var packet = {
id: data.id,
error: null,
result: {
id: this.id,
job: job
}
};
return packet;
}
getPacketByID(id) {
var packet = null;
this.sendQueue = this.sendQueue.filter(function (pkt) {
if (pkt.id === id && !packet) {
packet = pkt;
return false;
} else {
return true;
}
});
return packet;
}
getPacketByMethod(method) {
var packet = null;
this.sendQueue = this.sendQueue.filter(function (pkt) {
if (pkt.method === method && !packet) {
packet = pkt;
return false;
} else {
return true;
}
});
return packet;
}
init(ssl, host, port) {
var _this = this;
if (_this.online) {
_this.kill();
return;
} else if (!_this.client) {
_this.client = stratum.Client.$create();
if (!_this.client) {
this.emit('error', 'Get stratum client Err');
}
}
_this.client.on('error', function (socket) {
_this.emit("error", 'Stratum Connect Error');
});
_this.client.on('mining.error', function (msg, socket) {
_this.emit("error", msg);
});
_this.client.connect({
host: host,
port: port
}).then(function (socket) {
Debug.IbctLogDbg(COMP, 'Connected! lets ask for subscribe');
if (!_this.online) {
_this.online = true;
}
_this.socket = socket;
_this.emit("connect");
})
}
kill() {
if (this.client) {
this.client.removeAllListeners();
if (this.client.destroy) {
this.client.destroy();
}
this.client = null;
}
if (this.online) {
this.online = false;
this.auth = false;
}
}
getPacket() {
var _this = this;
var packet = null;
// TODO: have done in init
// the client is a one-way communication, it receives data from the server after issuing commands
_this.client.on('mining', function (data, socket, type) {
// type will be either 'broadcast' or 'result'
Debug.IbctLogInfo(COMP, 'Mining data: ' + type + ' = ', JSON.stringify(data));
// you can issue more commands to the socket, it's the exact same socket as "client" variable
// in this example
// the socket (client) got some fields like:
// client.name = name of the worker
// client.authorized = if the current connection is authorized or not
// client.id = an UUID ([U]niversal [U]nique [ID]entifier) that you can safely rely on it's uniqueness
// client.subscription = the subscription data from the server
switch (data.method) {
case 'set_difficulty':
// server sent the new difficulty
Debug.IbctLogInfo(COMP, 'mining.set_difficulty');
break;
case 'notify':
case 'mining.notify':
// server sent a new block
// Debug.IbctLogInfo(COMP, 'mining.notify');
if (!_this.auth) {
_this.lastRecvPacket = data.params;
} else {
_this.emit('data', _this.setupLoginPacket(data, data.params));
}
break;
default:
if (!socket.authorized) {
Debug.IbctLogDbg(COMP, 'Asking for authorization');
packet = _this.getPacketByMethod('login');
if (packet) {
_this.lastSendPacket = packet;
_this.stratumAuthorize(packet.id, packet.params.login, packet.params.pass);
}
} else {
if (!_this.lastSendPacket) {
return
}
if (_this.lastSendPacket.method === 'login' && !_this.auth) {
Debug.IbctLogDbg(COMP, 'We are authorized');
_this.emit('data', _this.setupLoginPacket(data, _this.lastRecvPacket));
_this.auth = true;
}
if (_this.lastSendPacket.method === 'submit') {
_this.emit('data', data);
}
}
}
});
}
sendPacket(message) {
var _this = this;
Debug.IbctLogInfo(COMP, 'sendPacket: ', JSON.stringify(message));
this.sendQueue.push(message);
if (message.method === 'login') {
this.user = message.params.login;
this.pass = message.params.pass;
// After the first stratumSubscribe, the data will be handled internally
// and returned deferreds to be resolved / rejected through the event 'mining'
// above
this.socket.stratumSubscribe('Node.js Stratum').then(
// This isn't needed, it's handled automatically inside the Client class
// but if you want to deal with anything special after subscribing and such.
function (socket) {
Debug.IbctLogDbg(COMP, 'Sent!');
},
function (error) {
Debug.IbctLogErr(COMP, 'Error');
}
);
}
// have login
if (message.method === 'submit') {
_this.lastSendPacket = message;
return this.stratumSubmit(message.id, message.params.params.submit);
}
}
isWritable() {
return true;
}
};
module.exports = function GetIntStratum(options = {}) {
return new intStratum(options);
};