ethstats-server/models/node.js

286 lines
4.8 KiB
JavaScript
Raw Normal View History

2014-12-04 22:35:09 +01:00
var geoip = require('geoip-lite');
2015-04-17 11:10:20 +02:00
var _ = require('lodash');
2014-12-04 22:35:09 +01:00
2015-04-28 09:43:56 +02:00
var MAX_HISTORY = 40;
2015-05-11 21:10:19 +02:00
var MAX_INACTIVE_TIME = 1000*60*60*4;
2015-04-06 16:08:36 +02:00
2015-02-17 06:12:44 +01:00
var Node = function Node(data)
2015-01-20 19:29:31 +01:00
{
2015-02-17 03:04:15 +01:00
this.id = null;
this.info = {};
this.geo = {}
this.stats = {
2015-01-20 19:29:31 +01:00
active: false,
mining: false,
2015-06-01 23:04:34 +02:00
hashrate: 0,
2015-02-17 03:04:15 +01:00
peers: 0,
pending: 0,
gasPrice: 0,
2015-02-17 10:30:41 +01:00
block: {
difficulty: 0,
number: 0,
gasLimit: 0,
2015-02-23 18:10:17 +01:00
timestamp: 0,
2015-04-29 07:49:43 +02:00
time: 0,
2015-02-23 18:10:17 +01:00
arrival: 0,
2015-03-27 10:44:07 +01:00
propagation: 0,
2015-03-27 20:05:43 +01:00
received: 0,
2015-04-24 07:37:03 +02:00
transactions: [],
uncles: []
2015-02-17 10:30:41 +01:00
},
2015-04-28 17:22:11 +02:00
propagationAvg: 0,
2015-02-23 14:57:41 +01:00
latency: 0,
2015-02-17 06:12:44 +01:00
uptime: 0,
2015-02-17 03:04:15 +01:00
lastUpdate: 0
};
2015-04-29 07:49:43 +02:00
2015-04-17 11:10:20 +02:00
this.history = new Array(MAX_HISTORY);
2015-04-29 07:49:43 +02:00
2015-03-27 11:28:55 +01:00
this.uptime = {
started: null,
history: []
};
2015-04-29 07:49:43 +02:00
this.init(data);
return this;
}
Node.prototype.init = function(data)
{
2015-04-17 11:10:20 +02:00
_.fill(this.history, -1);
2015-04-07 19:02:17 +02:00
2015-04-29 07:49:43 +02:00
if( this.id === null )
{
this.uptime.started = _.now();
2015-03-27 11:28:55 +01:00
this.setState(true);
}
2015-01-20 19:29:31 +01:00
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(data.id) )
2015-02-17 06:12:44 +01:00
this.id = data.id;
2015-04-29 07:49:43 +02:00
this.setInfo(data);
2015-02-18 07:06:41 +01:00
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(data.latency) )
2015-02-23 15:20:05 +01:00
this.stats.latency = data.latency;
2015-01-20 19:29:31 +01:00
return this;
}
2015-02-17 10:30:41 +01:00
Node.prototype.setInfo = function(data)
{
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(data.info) )
{
2015-02-17 10:30:41 +01:00
this.info = data.info;
2015-04-29 07:49:43 +02:00
if( _.isUndefined(data.info.canUpdateHistory) )
2015-04-28 09:43:56 +02:00
data.info.canUpdateHistory = false;
}
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(data.ip) )
{
if(data.ip === '::ffff:127.0.0.1')
data.ip = '84.117.82.122';
2015-02-17 10:30:41 +01:00
this.info.ip = data.ip;
2015-04-29 07:49:43 +02:00
this.setGeo();
2015-02-17 10:30:41 +01:00
}
2015-02-18 07:06:41 +01:00
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(data.spark) )
2015-02-18 07:06:41 +01:00
this.spark = data.spark;
2015-03-27 11:28:55 +01:00
2015-04-29 07:49:43 +02:00
var uptimeCnt = this.uptime.history.length;
if( uptimeCnt > 0 && this.uptime.history[uptimeCnt - 1].status === 'down' )
2015-03-27 11:28:55 +01:00
this.setState(true);
2015-04-29 07:49:43 +02:00
return this;
}
Node.prototype.setGeo = function()
{
this.geo = geoip.lookup(this.info.ip);
return this;
2015-02-17 10:30:41 +01:00
}
2015-02-17 06:12:44 +01:00
Node.prototype.getInfo = function()
{
2015-04-29 07:49:43 +02:00
return {
id: this.id,
info: this.info,
geo: this.geo,
stats: this.stats,
history: this.history
};
2015-02-17 06:12:44 +01:00
}
2015-04-17 11:10:20 +02:00
Node.prototype.setStats = function(stats, history)
2015-03-27 10:44:07 +01:00
{
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(stats) && !_.isUndefined(stats.block) && !_.isUndefined(stats.block.number) )
2015-03-27 10:44:07 +01:00
{
2015-04-17 11:10:20 +02:00
this.history = history;
2015-04-28 17:22:11 +02:00
var positives = _.filter(history, function(p) {
return p >= 0;
});
if(positives.length > 0)
2015-04-29 07:49:43 +02:00
stats.propagationAvg = Math.round( _.sum(positives) / positives.length );
2015-04-28 17:22:11 +02:00
else
stats.propagationAvg = 0;
2015-06-01 20:42:50 +02:00
if( !_.isUndefined(this.stats.latency) )
stats.latency = this.stats.latency;
2015-03-27 10:44:07 +01:00
this.stats = stats;
return this.getStats();
}
return false;
}
2015-06-01 21:51:31 +02:00
Node.prototype.setBlock = function(block, history)
{
2015-06-01 22:22:34 +02:00
if( !_.isUndefined(block) && !_.isUndefined(block.number) )
2015-06-01 21:51:31 +02:00
{
this.history = history;
var propagationAvg = 0;
var positives = _.filter(history, function(p) {
return p >= 0;
});
if(positives.length > 0)
propagationAvg = Math.round( _.sum(positives) / positives.length );
else
propagationAvg = 0;
this.stats.block = block;
this.stats.propagationAvg = propagationAvg;
return this.getBlockStats();
}
return false;
}
2015-06-01 20:42:50 +02:00
Node.prototype.setPending = function(stats)
{
if( !_.isUndefined(stats) && !_.isUndefined(stats.pending) )
{
this.stats.pending = stats.pending;
return {
id: this.id,
pending: this.stats.pending
};
}
return false;
}
2015-06-01 23:04:34 +02:00
Node.prototype.setBasicStats = function(stats)
{
if( !_.isUndefined(stats) )
{
this.stats.active = stats.active;
this.stats.mining = stats.mining;
this.stats.hashrate = stats.hashrate;
this.stats.peers = stats.peers;
this.stats.gasPrice = stats.gasPrice;
this.stats.uptime = stats.uptime;
return this.getBasicStats();
}
return false;
}
2015-04-03 06:00:06 +02:00
Node.prototype.setLatency = function(latency)
{
2015-04-29 07:49:43 +02:00
if( !_.isUndefined(latency) )
2015-04-03 06:00:06 +02:00
{
this.stats.latency = latency;
2015-04-29 07:49:43 +02:00
return {
id: this.id,
latency: latency
};
2015-04-03 06:00:06 +02:00
}
return false;
}
2015-02-17 06:12:44 +01:00
Node.prototype.getStats = function()
{
2015-04-29 07:49:43 +02:00
return {
id: this.id,
stats: this.stats,
history: this.history
};
2015-02-17 06:12:44 +01:00
}
2015-06-01 21:51:31 +02:00
Node.prototype.getBlockStats = function()
{
return {
id: this.id,
block: this.stats.block,
propagationAvg: this.stats.propagationAvg,
history: this.history
};
}
2015-06-01 23:04:34 +02:00
Node.prototype.getBasicStats = function()
{
return {
id: this.id,
stats: {
active: this.stats.active,
mining: this.stats.mining,
hashrate: this.stats.hashrate,
peers: this.stats.peers,
gasPrice: this.stats.gasPrice,
uptime: this.stats.uptime
}
};
}
2015-03-27 11:28:55 +01:00
Node.prototype.setState = function(active)
{
this.stats.active = active;
2015-04-29 07:49:43 +02:00
this.uptime.history.push({
status: (active ? 'up' : 'down'),
time: _.now()
});
2015-03-27 11:28:55 +01:00
}
Node.prototype.getBlockNumber = function()
{
return this.stats.block.number;
}
2015-04-28 09:43:56 +02:00
Node.prototype.canUpdate = function()
{
return this.info.canUpdateHistory || false;
}
2015-05-11 20:41:37 +02:00
Node.prototype.isInactiveAndOld = function()
{
if(this.stats.active)
return false;
var lastState = this.uptime.history[this.uptime.history.length -1];
if( !_.isUndefined(lastState) && !_.isUndefined(lastState.status) && !_.isUndefined(lastState.time) )
{
if( lastState.status === 'down' && (_.now() - lastState.time) > MAX_INACTIVE_TIME )
return true;
}
return false;
}
module.exports = Node;