Merge pull request #98 from cubedro/develop

version 0.0.7
This commit is contained in:
Marian OANCΞA 2015-04-29 23:43:03 +03:00
commit 95a853f08b
3 changed files with 154 additions and 92 deletions

5
app.js
View File

@ -1,7 +1,4 @@
var sleep = require('sleep'); 'use strict';
if(process.env.NODE_ENV === 'production')
sleep.sleep(15);
var nodeModel = require('./lib/node'); var nodeModel = require('./lib/node');

View File

@ -1,3 +1,5 @@
'use strict';
var web3 = require('web3'); var web3 = require('web3');
var _ = require('lodash'); var _ = require('lodash');
var os = require('os'); var os = require('os');
@ -9,19 +11,25 @@ var pjson = require('./../package.json');
var Primus = require('primus'), var Primus = require('primus'),
Emitter = require('primus-emit'), Emitter = require('primus-emit'),
Latency = require('primus-spark-latency'), Latency = require('primus-spark-latency'),
Socket; Socket, socket;
var ETH_VERSION, var ETH_VERSION,
NET_VERSION, NET_VERSION,
PROTOCOL_VERSION, PROTOCOL_VERSION,
API_VERSION; API_VERSION,
COINBASE;
var INSTANCE_NAME = process.env.INSTANCE_NAME; 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; 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({ Socket = Primus.createSocket({
transformer: 'websockets', transformer: 'websockets',
@ -36,50 +44,26 @@ if(process.env.NODE_ENV === 'production' && INSTANCE_NAME === "")
INSTANCE_NAME = shelljs.exec('ec2metadata --instance-id', {silent: true}).output; 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() 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 = { this.info = {
name: INSTANCE_NAME || (process.env.EC2_INSTANCE_ID || os.hostname()), name: INSTANCE_NAME || (process.env.EC2_INSTANCE_ID || os.hostname()),
contact: (process.env.CONTACT_DETAILS || ""), contact: (process.env.CONTACT_DETAILS || ""),
node: ETH_VERSION, coinbase: null,
net: NET_VERSION, node: null,
protocol: PROTOCOL_VERSION, net: null,
api: API_VERSION, protocol: null,
api: null,
port: (process.env.LISTENING_PORT || 30303), port: (process.env.LISTENING_PORT || 30303),
os: os.platform(), os: os.platform(),
os_v: os.release(), os_v: os.release(),
client: pjson.version, client: pjson.version,
canUpdateHistory: true, canUpdateHistory: true,
coinbase: COINBASE
}; };
this.id = _.camelCase(this.info.name); this.id = _.camelCase(this.info.name);
console.info(this.info);
this.stats = { this.stats = {
active: false, active: false,
listening: false, listening: false,
@ -100,23 +84,86 @@ function Node()
this._lastSent = 0; this._lastSent = 0;
this._latency = 0; this._latency = 0;
this.blocks = [];
this._Registrar = null; this._Registrar = null;
this._knownMiners = []; this._knownMiners = [];
this._socket = null;
this._web3 = false;
this._socket = false;
this.pendingFilter = false; this.pendingFilter = false;
this.chainFilter = false; this.chainFilter = false;
this.updateInterval = false; this.updateInterval = false;
this.pingInterval = false; this.pingInterval = false;
this.connectionInterval = false;
this._lastLatestLog = 0; this._lastLatestLog = 0;
this._lastPendingLog = 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() socket.on('open', function open()
{ {
console.info('The connection has been opened.'); console.info('==> The connection has been opened.');
console.info('Trying to login'); console.info('Trying to login');
socket.emit('hello', { socket.emit('hello', {
@ -125,18 +172,27 @@ function Node()
secret: WS_SECRET secret: WS_SECRET
}); });
}) })
.on('end', function end() .on('ready', function()
{ {
self._socket = false; self._socket = true;
console.error('Socket connection closed'); 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) .on('node-pong', function(data)
{ {
@ -147,32 +203,32 @@ function Node()
latency: latency 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; console.error("socket:", err);
self.sendUpdate(true);
console.info('The connection has been established.');
}) })
.on('history', function (data) .on('reconnecting', function reconnecting(opts)
{ {
console.info('Getting history.'); console.warn('We are scheduling a reconnect operation', opts);
var reqHistory = self.getHistory( data );
console.info('Sending history.');
socket.emit('history', {
id: self.id,
history: reqHistory
});
}); });
}
this.init(); Node.prototype.emit = function(message, payload)
{
return this; if(this._socket)
{
try {
socket.emit(message, payload);
}
catch (err) {
console.error("socket.emit:", err);
}
}
} }
Node.prototype.isActive = function() Node.prototype.isActive = function()
@ -203,6 +259,26 @@ Node.prototype.isActive = function()
return false; 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) Node.prototype.getBlock = function(number)
{ {
var block = { var block = {
@ -213,21 +289,22 @@ Node.prototype.getBlock = function(number)
}; };
if( _.isUndefined(number) ){ if( _.isUndefined(number) ){
try { number = "latest";
number = web3.eth.blockNumber; // try {
// number = web3.eth.blockNumber;
if(number === this.stats.block.number) // if(number === this.stats.block.number)
return this.stats.block; // return this.stats.block;
} // }
catch (err) { // catch (err) {
console.error("blockNumber:", err); // console.error("blockNumber:", err);
} // }
} }
try { try {
block = web3.eth.getBlock(number, true); block = web3.eth.getBlock(number, true);
if(block.hash != '?' && !_.isUndefined(block.difficulty) ) if( block.hash != '?' && !_.isUndefined(block.difficulty) )
{ {
block.difficulty = web3.toDecimal( block.difficulty ); block.difficulty = web3.toDecimal( block.difficulty );
} }
@ -474,19 +551,6 @@ Node.prototype.setWatches = function()
}, PING_INTERVAL); }, 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() Node.prototype.installContract = function()
{ {
try { try {
@ -502,9 +566,11 @@ Node.prototype.installContract = function()
Node.prototype.init = function() Node.prototype.init = function()
{ {
this.getInfo();
this.startSocketConnection();
this.installContract(); this.installContract();
this.update();
this.setWatches(); this.setWatches();
this.update();
} }
Node.prototype.stop = function() Node.prototype.stop = function()

View File

@ -1,7 +1,7 @@
{ {
"name": "eth-net-intelligence-api", "name": "eth-net-intelligence-api",
"description": "Ethereum Network Intelligence API", "description": "Ethereum Network Intelligence API",
"version": "0.0.6", "version": "0.0.7",
"private": true, "private": true,
"main": "./app.js", "main": "./app.js",
"directories": { "directories": {
@ -15,7 +15,6 @@
"primus-emit": "0.1.2", "primus-emit": "0.1.2",
"primus-spark-latency": "0.1.1", "primus-spark-latency": "0.1.1",
"shelljs": "0.4.0", "shelljs": "0.4.0",
"sleep": "2.0.0",
"web3": "0.3.4", "web3": "0.3.4",
"ws": "0.7.1" "ws": "0.7.1"
}, },