diff --git a/app.js b/app.js index fe1ca84..78a769f 100644 --- a/app.js +++ b/app.js @@ -1,7 +1,4 @@ -var sleep = require('sleep'); - -if(process.env.NODE_ENV === 'production') - sleep.sleep(15); +'use strict'; var nodeModel = require('./lib/node'); diff --git a/lib/node.js b/lib/node.js index 7d5da67..bececbc 100644 --- a/lib/node.js +++ b/lib/node.js @@ -1,3 +1,5 @@ +'use strict'; + var web3 = require('web3'); var _ = require('lodash'); var os = require('os'); @@ -9,19 +11,25 @@ var pjson = require('./../package.json'); var Primus = require('primus'), Emitter = require('primus-emit'), Latency = require('primus-spark-latency'), - Socket; + Socket, socket; var ETH_VERSION, NET_VERSION, PROTOCOL_VERSION, - API_VERSION; + API_VERSION, + COINBASE; var INSTANCE_NAME = process.env.INSTANCE_NAME; -var COINBASE = ''; +var WS_SECRET = process.env.WS_SECRET || "eth-net-stats-has-a-secret"; var Contract = null; -web3.setProvider(new web3.providers.HttpProvider('http://' + (process.env.RPC_HOST || 'localhost') + ':' + (process.env.RPC_PORT || '8080'))); +var PENDING_WORKS = true; +var MAX_BLOCKS_HISTORY = 40; +var UPDATE_INTERVAL = 5000; +var PING_INTERVAL = 2000; +var MINERS_LIMIT = 5; +var MAX_HISTORY_UPDATE = 50; Socket = Primus.createSocket({ transformer: 'websockets', @@ -36,50 +44,26 @@ if(process.env.NODE_ENV === 'production' && INSTANCE_NAME === "") INSTANCE_NAME = shelljs.exec('ec2metadata --instance-id', {silent: true}).output; } -var socket = new Socket(process.env.WS_SERVER || 'ws://localhost:3000'); -var WS_SECRET = process.env.WS_SECRET || "eth-net-stats-has-a-secret"; - -var PENDING_WORKS = true; -var MAX_BLOCKS_HISTORY = 40; -var UPDATE_INTERVAL = 5000; -var PING_INTERVAL = 2000; -var MINERS_LIMIT = 5; -var MAX_HISTORY_UPDATE = 50; function Node() { - var self = this; - - try { - ETH_VERSION = web3.version.client; - NET_VERSION = web3.version.network; - PROTOCOL_VERSION = web3.toDecimal(web3.version.ethereum); - API_VERSION = web3.version.api; - COINBASE = web3.eth.coinbase; - } - catch (err) { - console.error("Couldn't get version"); - } - this.info = { name: INSTANCE_NAME || (process.env.EC2_INSTANCE_ID || os.hostname()), contact: (process.env.CONTACT_DETAILS || ""), - node: ETH_VERSION, - net: NET_VERSION, - protocol: PROTOCOL_VERSION, - api: API_VERSION, + coinbase: null, + node: null, + net: null, + protocol: null, + api: null, port: (process.env.LISTENING_PORT || 30303), os: os.platform(), os_v: os.release(), client: pjson.version, canUpdateHistory: true, - coinbase: COINBASE }; this.id = _.camelCase(this.info.name); - console.info(this.info); - this.stats = { active: false, listening: false, @@ -100,23 +84,86 @@ function Node() this._lastSent = 0; this._latency = 0; - this.blocks = []; - this._Registrar = null; this._knownMiners = []; - this._socket = null; + + this._web3 = false; + this._socket = false; + this.pendingFilter = false; this.chainFilter = false; this.updateInterval = false; this.pingInterval = false; + this.connectionInterval = false; this._lastLatestLog = 0; this._lastPendingLog = 0; + this._called = 0 + this.startWeb3Connection(); + + return this; +} + +Node.prototype.startWeb3Connection = function() +{ + console.info("==> Starting eth connection"); + + web3.setProvider( new web3.providers.HttpProvider('http://' + (process.env.RPC_HOST || 'localhost') + ':' + (process.env.RPC_PORT || '8080')) ); + + this.checkWeb3Connection(); +} + +Node.prototype.checkWeb3Connection = function() +{ + var self = this; + + if(!this._web3) + { + try { + var tmp = web3.version.client; + + if( !_.isUndefined(tmp) ) + { + console.log('eth ', tmp); + console.info("==> Ethereum connection established"); + + this._web3 = true; + this.init(); + + return true; + } + } + catch(err) + { + console.error('xx> Ethereum connection atempt #' + this.called++ + ' failed; ', err); + + process.nextTick( function() + { + self.checkWeb3Connection(); + }); + } + } +} + +Node.prototype.startSocketConnection = function() +{ + console.info("==> Starting socket connection"); + + socket = new Socket( process.env.WS_SERVER || 'ws://localhost:3000' ); + + this.setupSockets(); +} + +Node.prototype.setupSockets = function() +{ + var self = this; + + // Setup events socket.on('open', function open() { - console.info('The connection has been opened.'); + console.info('==> The connection has been opened.'); console.info('Trying to login'); socket.emit('hello', { @@ -125,18 +172,27 @@ function Node() secret: WS_SECRET }); }) - .on('end', function end() + .on('ready', function() { - self._socket = false; - console.error('Socket connection closed'); + self._socket = true; + self.sendUpdate(true); + + console.info('==> The connection has been established.'); }) - .on('error', function error(err) + .on('data', function incoming(data) { - console.error("socket:", err); + console.info('Received some data', data); }) - .on('reconnecting', function reconnecting(opts) + .on('history', function (data) { - console.warn('We are scheduling a reconnect operation', opts); + console.info('==> Getting history'); + + var reqHistory = self.getHistory( data ); + + socket.emit('history', { + id: self.id, + history: reqHistory + }); }) .on('node-pong', function(data) { @@ -147,32 +203,32 @@ function Node() latency: latency }); }) - .on('data', function incoming(data) + .on('end', function end() { - console.info('Received some data', data); + self._socket = false; + console.error('xx> Socket connection closed'); }) - .on('ready', function() + .on('error', function error(err) { - self._socket = true; - self.sendUpdate(true); - - console.info('The connection has been established.'); + console.error("socket:", err); }) - .on('history', function (data) + .on('reconnecting', function reconnecting(opts) { - console.info('Getting history.'); - var reqHistory = self.getHistory( data ); - - console.info('Sending history.'); - socket.emit('history', { - id: self.id, - history: reqHistory - }); + console.warn('We are scheduling a reconnect operation', opts); }); +} - this.init(); - - return this; +Node.prototype.emit = function(message, payload) +{ + if(this._socket) + { + try { + socket.emit(message, payload); + } + catch (err) { + console.error("socket.emit:", err); + } + } } Node.prototype.isActive = function() @@ -203,6 +259,26 @@ Node.prototype.isActive = function() return false; } +Node.prototype.getInfo = function() +{ + try { + this.info.coinbase = web3.eth.coinbase; + this.info.node = web3.version.client; + this.info.net = web3.version.network; + this.info.protocol = web3.toDecimal(web3.version.ethereum); + this.info.api = web3.version.api; + + console.info(this.info); + + return true; + } + catch (err) { + console.error("Couldn't get version"); + } + + return false; +} + Node.prototype.getBlock = function(number) { var block = { @@ -213,21 +289,22 @@ Node.prototype.getBlock = function(number) }; if( _.isUndefined(number) ){ - try { - number = web3.eth.blockNumber; + number = "latest"; + // try { + // number = web3.eth.blockNumber; - if(number === this.stats.block.number) - return this.stats.block; - } - catch (err) { - console.error("blockNumber:", err); - } + // if(number === this.stats.block.number) + // return this.stats.block; + // } + // catch (err) { + // console.error("blockNumber:", err); + // } } try { block = web3.eth.getBlock(number, true); - if(block.hash != '?' && !_.isUndefined(block.difficulty) ) + if( block.hash != '?' && !_.isUndefined(block.difficulty) ) { block.difficulty = web3.toDecimal( block.difficulty ); } @@ -474,19 +551,6 @@ Node.prototype.setWatches = function() }, PING_INTERVAL); } -Node.prototype.emit = function(message, payload) -{ - if(this._socket) - { - try { - socket.emit(message, payload); - } - catch (err) { - console.error("socket.emit:", err); - } - } -} - Node.prototype.installContract = function() { try { @@ -502,9 +566,11 @@ Node.prototype.installContract = function() Node.prototype.init = function() { + this.getInfo(); + this.startSocketConnection(); this.installContract(); - this.update(); this.setWatches(); + this.update(); } Node.prototype.stop = function() diff --git a/package.json b/package.json index a07b719..9478efa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "eth-net-intelligence-api", "description": "Ethereum Network Intelligence API", - "version": "0.0.6", + "version": "0.0.7", "private": true, "main": "./app.js", "directories": { @@ -15,7 +15,6 @@ "primus-emit": "0.1.2", "primus-spark-latency": "0.1.1", "shelljs": "0.4.0", - "sleep": "2.0.0", "web3": "0.3.4", "ws": "0.7.1" },