ethstats-cli
Version:
EthStats - CLI Client
441 lines (364 loc) • 15.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _url = _interopRequireDefault(require("url"));
var _web = _interopRequireDefault(require("web3-0.x-wrapper"));
var _parallel = _interopRequireDefault(require("async/parallel"));
var _Abstract2 = _interopRequireDefault(require("./Abstract.js"));
var _mapSeries = _interopRequireDefault(require("async/mapSeries"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Http =
/*#__PURE__*/
function (_Abstract) {
_inherits(Http, _Abstract);
function Http(diContainer) {
var _this;
_classCallCheck(this, Http);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Http).call(this, diContainer));
_this.CHECK_LATEST_FILTER_INTERVAL = 300000;
_this.web3 = new _web.default();
_this.checkLatestBlocksFilterInterval = null;
return _this;
}
_createClass(Http, [{
key: "connect",
value: function connect() {
var _this2 = this;
if (!this.web3.currentProvider) {
var urlObject = new _url.default.URL(this.url);
this.log.echo("Setting Web3 provider to \"".concat(urlObject.origin, "\""));
this.web3.setProvider(new this.web3.providers.HttpProvider(urlObject.origin, 0, urlObject.username, urlObject.password));
}
if (!this.web3.isConnected()) {
this.log.warning('No connection found with the node. Waiting to connect...');
}
this.checkConnection();
if (this.connectionInterval === null) {
this.connectionInterval = setInterval(function () {
_this2.checkConnection();
}, this.CONNECTION_INTERVAL);
}
}
}, {
key: "checkConnection",
value: function checkConnection() {
var _this3 = this;
this.log.debug('Check connection');
if (this.web3.isConnected()) {
if (!this.isConnected) {
this.isConnected = true;
this.lastBlock = null;
this.start();
this.log.echo('Connection established with the node');
}
if (!this.server.isLoggedIn) {
this.getLoginInfo().then(function (loginInfos) {
_this3.usage.setNodeProcessName(loginInfos.node);
_this3.server.login(loginInfos);
});
}
} else {
if (this.isConnected) {
this.isConnected = false;
this.stop();
this.log.warning('Connection lost with the node. Waiting to reconnect...');
}
if (this.server.isLoggedIn) {
this.server.logout();
}
}
}
}, {
key: "getLoginInfo",
value: function () {
var _getLoginInfo = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee() {
var result;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
result = {
nodeName: this.config.configStore.get('nodeName'),
secretKey: this.config.configStore.get('secretKey'),
coinbase: null,
node: null,
net: null,
protocol: null,
api: this.web3.version.api,
os: this.os.type(),
osVersion: this.os.release(),
client: this.pkg.version,
cpu: null,
memory: null,
disk: null
};
try {
result.coinbase = '0x22ea9f6b28db76a7162054c05ed812deb2f519cd';
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
try {
result.node = this.web3.version.node;
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
try {
result.net = this.web3.version.network;
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
try {
result.protocol = this.web3.version.ethereum;
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
_context.next = 7;
return this.hwInfo.getCpuInfo();
case 7:
result.cpu = _context.sent;
_context.next = 10;
return this.hwInfo.getMemoryInfo();
case 10:
result.memory = _context.sent;
_context.next = 13;
return this.hwInfo.getDiskInfo();
case 13:
result.disk = _context.sent;
return _context.abrupt("return", result);
case 15:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function getLoginInfo() {
return _getLoginInfo.apply(this, arguments);
}
return getLoginInfo;
}()
}, {
key: "start",
value: function start() {
var _this4 = this;
this.log.debug('Start client'); // Set chain watchers
this.setLatestBlocksFilter(); // Set isSyncing watcher
this.web3.eth.isSyncing(function (error, data) {
if (error) {
_this4.log.error(_this4.errorHandler.resolve(error));
} else {
_this4.syncStatus(data);
}
});
this.statsInterval = setInterval(function () {
_this4.getStats();
}, this.STATS_INTERVAL);
this.usageInterval = setInterval(function () {
_this4.usage.getStats();
}, this.USAGE_INTERVAL);
this.checkLatestBlocksFilter();
}
}, {
key: "stop",
value: function stop() {
var stopConnectionInterval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
this.log.debug('Stop client');
try {
this.web3.reset(false);
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
if (stopConnectionInterval) {
clearInterval(this.connectionInterval);
}
clearInterval(this.statsInterval);
clearInterval(this.usageInterval);
clearInterval(this.checkLatestBlocksFilterInterval);
}
}, {
key: "setLatestBlocksFilter",
value: function setLatestBlocksFilter() {
var _this5 = this;
try {
this.web3.eth.filter('latest').watch(function (error, hash) {
if (!error) {
hash = hash.value === undefined ? hash : hash.value;
_this5.blocksQueue.push(hash);
}
});
} catch (error) {
this.log.error(this.errorHandler.resolve(error));
}
}
}, {
key: "checkLatestBlocksFilter",
value: function checkLatestBlocksFilter() {
var _this6 = this;
this.checkLatestBlocksFilterInterval = setInterval(function () {
if (_this6.isConnected) {
var clientLastBlockNumber = _this6.lastBlock === null ? 0 : parseInt(_this6.lastBlock.number, 10);
var nodeLastBlockNumber = 0;
try {
nodeLastBlockNumber = parseInt(_this6.web3.eth.blockNumber, 10);
} catch (error) {
_this6.log.error(_this6.errorHandler.resolve(error));
}
if (clientLastBlockNumber > 0 && nodeLastBlockNumber > clientLastBlockNumber) {
_this6.log.info("Client last block ".concat(clientLastBlockNumber, " is behind Node last block ").concat(nodeLastBlockNumber, ", resetting filters..."));
_this6.stop();
_this6.start();
}
}
}, this.CHECK_LATEST_FILTER_INTERVAL);
}
}, {
key: "getStats",
value: function getStats() {
var _this7 = this;
this.log.debug('Get stats');
(0, _parallel.default)({
peers: function peers(callback) {
_this7.web3.net.getPeerCount(function (error, data) {
if (error) {
_this7.log.error(_this7.errorHandler.resolve(error));
}
data = data ? data : 0;
return callback(null, data);
});
},
gasPrice: function gasPrice(callback) {
_this7.web3.eth.getGasPrice(function (error, data) {
if (error) {
_this7.log.error(_this7.errorHandler.resolve(error));
}
data = data ? data.toString() : 0;
return callback(null, data);
});
},
mining: function mining(callback) {
_this7.web3.eth.getMining(function (error, data) {
if (error) {
_this7.log.error(_this7.errorHandler.resolve(error));
}
data = data ? data : false;
return callback(null, data);
});
},
hashrate: function hashrate(callback) {
_this7.web3.eth.getHashrate(function (error, data) {
if (error) {
_this7.log.error(_this7.errorHandler.resolve(error));
}
data = data ? data : 0;
return callback(null, data);
});
},
pendingTXs: function pendingTXs(callback) {
_this7.web3.eth.getBlockTransactionCount('pending', function (error, data) {
if (error) {
_this7.log.error(_this7.errorHandler.resolve(error));
}
data = data ? data : 0;
return callback(null, data);
});
}
}, function (error, stats) {
_this7.server.send('stats', stats);
});
}
}, {
key: "getBlock",
value: function getBlock(number, asyncCallback) {
var _this8 = this;
this.web3.eth.getBlock(number, false, function (error, block) {
if (error) {
_this8.log.error(_this8.errorHandler.resolve(error));
if (asyncCallback) {
asyncCallback();
}
} else {
_this8.log.debug("Got block: \"".concat(block.number, "\""));
_this8.processBlock(block);
if (asyncCallback) {
asyncCallback();
}
}
});
}
}, {
key: "getBlockHashes",
value: function getBlockHashes(blockNumber) {
var _this9 = this;
var result = {
blockNumber: null,
blockHash: null,
blockParentHash: null
};
this.web3.eth.getBlock(blockNumber, false, function (error, block) {
if (error) {
_this9.log.error(_this9.errorHandler.resolve(error));
} else if (block === null) {
_this9.log.error("Could not get block \"".concat(blockNumber, "\". Your node might be not fully synced."), false, true);
} else {
result.blockNumber = parseInt(block.number, 10);
result.blockHash = block.hash.toString();
result.blockParentHash = block.parentHash.toString();
}
_this9.server.send('checkChainData', result);
});
}
}, {
key: "getBlocks",
value: function getBlocks(range) {
var _this10 = this;
(0, _mapSeries.default)(range, function (blockNumber, callback) {
_this10.log.debug("History get block: \"".concat(blockNumber, "\""));
_this10.web3.eth.getBlock(blockNumber, false, callback);
}, function (error, results) {
if (error) {
_this10.log.error("Error getting block history: ".concat(error));
results = [];
}
_this10.server.send('getBlocksData', results);
});
}
}, {
key: "getValidators",
value: function getValidators(block) {
var _this11 = this;
var result = {
blockNumber: block.number,
blockHash: block.hash,
validators: []
};
this.web3._requestManager.sendAsync({
method: 'clique_getSignersAtHash',
params: [block.hash]
}, function (error, validators) {
if (error) {
_this11.log.error("Could not get validators for block ".concat(block.number, "::").concat(block.hash, " => ").concat(error.message));
} else {
result.validators = validators;
_this11.server.send('validators', result);
}
});
}
}]);
return Http;
}(_Abstract2.default);
exports.default = Http;