Add masternodes page/feature
-Added a new "Masternodes" page which displays the current list of masternodes on the network -/api/getmasternodelist is no longer publicly accessible and has been replaced by /ext/getmasternodelist which returns the masternode list from local collection instead of directly from wallet -Added new masternode sync options to sync.js and sync.sh -Added new masternodes_last_updated field to the Stats collection -Updated delete_database.sh and restore_backup.sh to include support for the new masternodes collection -Network header menu icon changed to allow the new Masternodes menu item to use the old network icon
This commit is contained in:
@@ -115,6 +115,7 @@ sync.sh (located in scripts/) is used for updating the local databases. This scr
|
|||||||
reindex-txcount Rescan and flatten the tx count value for faster access
|
reindex-txcount Rescan and flatten the tx count value for faster access
|
||||||
market Updates market summaries, orderbooks, trade history + charts
|
market Updates market summaries, orderbooks, trade history + charts
|
||||||
peers Updates peer info based on local wallet connections
|
peers Updates peer info based on local wallet connections
|
||||||
|
masternodes Updates the list of active masternodes on the network
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- 'current block' is the latest created block when script is executed.
|
- 'current block' is the latest created block when script is executed.
|
||||||
@@ -126,11 +127,12 @@ sync.sh (located in scripts/) is used for updating the local databases. This scr
|
|||||||
|
|
||||||
**crontab**
|
**crontab**
|
||||||
|
|
||||||
*Example crontab; update index every minute, market data every 2 minutes and peers every 5 minutes*
|
*Example crontab; update index every minute, market data every 2 minutes, peers and masternodes every 5 minutes*
|
||||||
|
|
||||||
*/1 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs update > /dev/null 2>&1
|
*/1 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs update > /dev/null 2>&1
|
||||||
*/2 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs market > /dev/null 2>&1
|
*/2 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs market > /dev/null 2>&1
|
||||||
*/5 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs peers > /dev/null 2>&1
|
*/5 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs peers > /dev/null 2>&1
|
||||||
|
*/5 * * * * /path/to/explorer/scripts/sync.sh /path/to/nodejs masternodes > /dev/null 2>&1
|
||||||
|
|
||||||
### Wallet
|
### Wallet
|
||||||
|
|
||||||
|
|||||||
@@ -346,6 +346,24 @@ app.use('/ext/connections', function(req,res){
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// get the list of masternodes from local collection
|
||||||
|
app.use('/ext/getmasternodelist', function(req, res) {
|
||||||
|
// check if the getmasternodelist api is enabled or else check the headers to see if it matches an internal ajax request from the explorer itself (TODO: come up with a more secure method of whitelisting ajax calls from the explorer)
|
||||||
|
if (settings.public_api.ext['getmasternodelist'] || (req.headers['x-requested-with'] != null && req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest' && req.headers.referer != null && req.headers.accept.indexOf('text/javascript') > -1 && req.headers.accept.indexOf('application/json') > -1)) {
|
||||||
|
// get the masternode list from local collection
|
||||||
|
db.get_masternodes(function(masternodes) {
|
||||||
|
// loop through masternode list and remove the mongo _id and __v keys
|
||||||
|
for (i = 0; i < masternodes.length; i++) {
|
||||||
|
delete masternodes[i]['_doc']['_id'];
|
||||||
|
delete masternodes[i]['_doc']['__v'];
|
||||||
|
}
|
||||||
|
// return masternode list
|
||||||
|
res.send(masternodes);
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
res.end('This method is disabled');
|
||||||
|
});
|
||||||
|
|
||||||
// locals
|
// locals
|
||||||
app.set('title', settings.title);
|
app.set('title', settings.title);
|
||||||
app.set('explorer_version', package_metadata.version);
|
app.set('explorer_version', package_metadata.version);
|
||||||
@@ -390,9 +408,12 @@ app.set('labels', settings.labels);
|
|||||||
app.set('homelink', settings.homelink);
|
app.set('homelink', settings.homelink);
|
||||||
app.set('logoheight', settings.logoheight);
|
app.set('logoheight', settings.logoheight);
|
||||||
app.set('burned_coins', settings.burned_coins);
|
app.set('burned_coins', settings.burned_coins);
|
||||||
app.set('public_api', settings.public_api);
|
|
||||||
app.set('api_cmds', settings.api_cmds);
|
app.set('api_cmds', settings.api_cmds);
|
||||||
|
|
||||||
|
// Always disable the rpc masternode list cmd from public apis
|
||||||
|
settings.public_api['rpc']['getmasternodelist'] = false;
|
||||||
|
app.set('public_api', settings.public_api);
|
||||||
|
|
||||||
app.set('sticky_header', settings.sticky_header);
|
app.set('sticky_header', settings.sticky_header);
|
||||||
app.set('sticky_footer', settings.sticky_footer);
|
app.set('sticky_footer', settings.sticky_footer);
|
||||||
|
|
||||||
|
|||||||
+214
-38
@@ -1,6 +1,7 @@
|
|||||||
var mongoose = require('mongoose')
|
var mongoose = require('mongoose')
|
||||||
, Stats = require('../models/stats')
|
, Stats = require('../models/stats')
|
||||||
, Markets = require('../models/markets')
|
, Markets = require('../models/markets')
|
||||||
|
, Masternode = require('../models/masternode')
|
||||||
, Address = require('../models/address')
|
, Address = require('../models/address')
|
||||||
, AddressTx = require('../models/addresstx')
|
, AddressTx = require('../models/addresstx')
|
||||||
, Tx = require('../models/tx')
|
, Tx = require('../models/tx')
|
||||||
@@ -250,49 +251,18 @@ module.exports = {
|
|||||||
return fs.existsSync('./tmp/show_sync_message.tmp');
|
return fs.existsSync('./tmp/show_sync_message.tmp');
|
||||||
},
|
},
|
||||||
|
|
||||||
update_label: function(hash, message, cb) {
|
update_label: function(hash, claim_name, cb) {
|
||||||
find_address(hash, false, function(address) {
|
find_address(hash, false, function(address) {
|
||||||
if (address) {
|
if (address) {
|
||||||
Address.updateOne({a_id: hash}, {
|
Address.updateOne({a_id: hash}, {
|
||||||
name: message
|
name: claim_name
|
||||||
}, function() {
|
}, function() {
|
||||||
// ensure that if this address exists in the richlist that it displays the new alias
|
// update claim name in richlist
|
||||||
module.exports.get_richlist(settings.coin, function(richlist) {
|
module.exports.update_richlist_claim_name(hash, claim_name, function() {
|
||||||
var updated = false;
|
// update claim name in masternode list
|
||||||
// loop through received addresses
|
module.exports.update_masternode_claim_name(hash, claim_name, function() {
|
||||||
for (r = 0; r < richlist.received.length; r++) {
|
|
||||||
// check if this is the correct address
|
|
||||||
if (richlist.received[r].a_id == hash) {
|
|
||||||
// update the claim name
|
|
||||||
richlist.received[r]['name'] = message;
|
|
||||||
// mark as updated
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// loop through balance addresses
|
|
||||||
for (b = 0; b < richlist.balance.length; b++) {
|
|
||||||
// check if this is the correct address
|
|
||||||
if (richlist.balance[b].a_id == hash) {
|
|
||||||
// update the claim name
|
|
||||||
richlist.balance[b]['name'] = message;
|
|
||||||
// mark as updated
|
|
||||||
updated = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check if the address was updated in the richlist
|
|
||||||
if (updated) {
|
|
||||||
// save the richlist back to collection
|
|
||||||
Richlist.updateOne({coin: settings.coin}, {
|
|
||||||
received: richlist.received,
|
|
||||||
balance: richlist.balance
|
|
||||||
}, function() {
|
|
||||||
// finished updating the claim label
|
|
||||||
return cb('');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// finished updating the claim label
|
|
||||||
return cb('');
|
return cb('');
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -302,6 +272,89 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
update_richlist_claim_name: function(hash, claim_name, cb) {
|
||||||
|
// check if the richlist is enabled
|
||||||
|
if (settings.display.richlist) {
|
||||||
|
// ensure that if this address exists in the richlist that it displays the new alias
|
||||||
|
module.exports.get_richlist(settings.coin, function(richlist) {
|
||||||
|
var updated = false;
|
||||||
|
// loop through received addresses
|
||||||
|
for (r = 0; r < richlist.received.length; r++) {
|
||||||
|
// check if this is the correct address
|
||||||
|
if (richlist.received[r].a_id == hash) {
|
||||||
|
// update the claim name
|
||||||
|
richlist.received[r]['name'] = claim_name;
|
||||||
|
// mark as updated
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// loop through balance addresses
|
||||||
|
for (b = 0; b < richlist.balance.length; b++) {
|
||||||
|
// check if this is the correct address
|
||||||
|
if (richlist.balance[b].a_id == hash) {
|
||||||
|
// update the claim name
|
||||||
|
richlist.balance[b]['name'] = claim_name;
|
||||||
|
// mark as updated
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if the address was updated in the richlist
|
||||||
|
if (updated) {
|
||||||
|
// save the richlist back to collection
|
||||||
|
Richlist.updateOne({coin: settings.coin}, {
|
||||||
|
received: richlist.received,
|
||||||
|
balance: richlist.balance
|
||||||
|
}, function() {
|
||||||
|
// finished updating the claim label
|
||||||
|
return cb('');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// finished updating the claim label
|
||||||
|
return cb('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// richlist is not enabled so nothing to update
|
||||||
|
return cb('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update_masternode_claim_name: function(hash, claim_name, cb) {
|
||||||
|
// check if the masternode list is enabled
|
||||||
|
if (settings.display.masternodes) {
|
||||||
|
// ensure that if this address exists in the masternode that it displays the new alias
|
||||||
|
module.exports.get_masternodes(function(masternodes) {
|
||||||
|
var updated = false;
|
||||||
|
// loop through masternode addresses
|
||||||
|
for (m = 0; m < masternodes.length; m++) {
|
||||||
|
// check if this is the correct address
|
||||||
|
if (masternodes[m].addr == hash) {
|
||||||
|
// update the claim name
|
||||||
|
masternodes[m]['claim_name'] = claim_name;
|
||||||
|
// mark as updated
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if the address was updated in the masternode list
|
||||||
|
if (updated) {
|
||||||
|
// save the updated masternode back to collection
|
||||||
|
Masternode.updateOne({addr: hash}, {
|
||||||
|
claim_name: claim_name
|
||||||
|
}, function() {
|
||||||
|
// finished updating the claim label
|
||||||
|
return cb('');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// finished updating the claim label
|
||||||
|
return cb('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// masternode list is not enabled so nothing to update
|
||||||
|
return cb('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
check_stats: function(coin, cb) {
|
check_stats: function(coin, cb) {
|
||||||
Stats.findOne({coin: coin}, function(err, stats) {
|
Stats.findOne({coin: coin}, function(err, stats) {
|
||||||
if(stats) {
|
if(stats) {
|
||||||
@@ -993,6 +1046,129 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// determine if masternode exists and save masternode to collection
|
||||||
|
save_masternode: function (raw_masternode, cb) {
|
||||||
|
// lookup masternode in local collection
|
||||||
|
module.exports.find_masternode(raw_masternode.txhash, raw_masternode.outidx, function (masternode) {
|
||||||
|
// determine if the claim address feature is enabled
|
||||||
|
if (settings.display.claim_address) {
|
||||||
|
// claim address is enabled so lookup the address claim name
|
||||||
|
find_address(raw_masternode.addr, false, function(address) {
|
||||||
|
if (address) {
|
||||||
|
// save claim name to masternode obejct
|
||||||
|
raw_masternode.claim_name = address.name;
|
||||||
|
} else {
|
||||||
|
// save blank claim name to masternode obejct
|
||||||
|
raw_masternode.claim_name = '';
|
||||||
|
}
|
||||||
|
// add/update the masternode
|
||||||
|
module.exports.add_update_masternode(raw_masternode, (masternode == null), function(success) {
|
||||||
|
return cb(success);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// claim address is disabled so add/update the masternode
|
||||||
|
module.exports.add_update_masternode(raw_masternode, (masternode == null), function(success) {
|
||||||
|
return cb(success);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// add or update a single masternode
|
||||||
|
add_update_masternode(masternode, add, cb) {
|
||||||
|
if (!masternode.txhash == null || !masternode.outidx == null) {
|
||||||
|
console.log('Masternode Update - TX or Outidx is missing');
|
||||||
|
console.log(masternode.txhash);
|
||||||
|
console.log(masternode.outidx);
|
||||||
|
return cb(false);
|
||||||
|
} else {
|
||||||
|
var mn = new Masternode({
|
||||||
|
rank: masternode.rank,
|
||||||
|
network: masternode.network,
|
||||||
|
txhash: masternode.txhash,
|
||||||
|
outidx: masternode.outidx,
|
||||||
|
status: masternode.status,
|
||||||
|
addr: masternode.addr,
|
||||||
|
version: masternode.version,
|
||||||
|
lastseen: masternode.lastseen,
|
||||||
|
activetime: masternode.activetime,
|
||||||
|
lastpaid: masternode.lastpaid,
|
||||||
|
claim_name: (masternode.claim_name == null ? '' : masternode.claim_name)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (add) {
|
||||||
|
// add new masternode to collection
|
||||||
|
mn.save(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return cb(false);
|
||||||
|
} else
|
||||||
|
return cb(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// update existing masternode in local collection
|
||||||
|
Masternode.updateOne({ txhash: masternode.txhash, outidx: masternode.outidx }, masternode, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return cb(false);
|
||||||
|
} else
|
||||||
|
return cb(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// find masternode by txid and offset
|
||||||
|
find_masternode: function (txhash, outidx, cb) {
|
||||||
|
Masternode.findOne({ txhash: txhash, outidx: outidx }, function (err, masternode) {
|
||||||
|
if (err)
|
||||||
|
return cb(null);
|
||||||
|
else {
|
||||||
|
if (masternode)
|
||||||
|
return cb(masternode);
|
||||||
|
else
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// remove masternodes older than 24 hours
|
||||||
|
remove_old_masternodes: function (cb) {
|
||||||
|
Masternode.deleteMany({ lastseen: { $lte: (Math.floor(Date.now() / 1000) - 86400) } }, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return cb();
|
||||||
|
} else
|
||||||
|
return cb();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// get the list of masternodes from local collection
|
||||||
|
get_masternodes: function (cb) {
|
||||||
|
Masternode.find({}, function (err, masternodes) {
|
||||||
|
if (err)
|
||||||
|
return cb([]);
|
||||||
|
else
|
||||||
|
return cb(masternodes);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// updates last_updated stats; called by sync.js
|
||||||
|
update_last_updated_stats: function (coin, param, cb) {
|
||||||
|
if (param.masternodes_last_updated) {
|
||||||
|
// update masternode last updated date
|
||||||
|
Stats.updateOne({ coin: coin }, {
|
||||||
|
masternodes_last_updated: param.masternodes_last_updated
|
||||||
|
}, function () {
|
||||||
|
return cb(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// invalid option
|
||||||
|
return cb(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
populate_claim_address_names: function(tx, cb) {
|
populate_claim_address_names: function(tx, cb) {
|
||||||
var addresses = [];
|
var addresses = [];
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,34 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get_masternodelist: function(cb) {
|
||||||
|
var cmd = prepareRpcCommand(settings.api_cmds.getmasternodelist);
|
||||||
|
|
||||||
|
if (!(cmd.method == '' && cmd.parameters.length == 0)) {
|
||||||
|
if (settings.use_rpc) {
|
||||||
|
rpcCommand([{method:cmd.method, parameters: cmd.parameters}], function(response) {
|
||||||
|
// check if an error msg was received from the rpc server
|
||||||
|
if (response == 'There was an error. Check your console.')
|
||||||
|
return cb(null);
|
||||||
|
else
|
||||||
|
return cb(response);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var uri = base_url + 'getmasternodelist';
|
||||||
|
request({uri: uri, json: true, headers: {'User-Agent': 'eiquidus'}}, function (error, response, body) {
|
||||||
|
// check if an error msg was received from the web api server
|
||||||
|
if (body == 'There was an error. Check your console.')
|
||||||
|
return cb(null);
|
||||||
|
else
|
||||||
|
return cb(body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// cmd not in use. return null.
|
||||||
|
return cb(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
get_masternodecount: function(cb) {
|
get_masternodecount: function(cb) {
|
||||||
var cmd = prepareRpcCommand(settings.api_cmds.getmasternodecount);
|
var cmd = prepareRpcCommand(settings.api_cmds.getmasternodecount);
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -92,6 +92,7 @@ exports.display = {
|
|||||||
"richlist": true,
|
"richlist": true,
|
||||||
"movement": true,
|
"movement": true,
|
||||||
"network": true,
|
"network": true,
|
||||||
|
"masternodes": true,
|
||||||
"claim_address": true,
|
"claim_address": true,
|
||||||
"claim_address_header_menu": true,
|
"claim_address_header_menu": true,
|
||||||
"page_header_bgcolor": "",
|
"page_header_bgcolor": "",
|
||||||
@@ -201,7 +202,6 @@ exports.public_api = {
|
|||||||
"getnetworkhashps": true,
|
"getnetworkhashps": true,
|
||||||
"getvotelist": true,
|
"getvotelist": true,
|
||||||
"getmasternodecount": true,
|
"getmasternodecount": true,
|
||||||
"getmasternodelist": true,
|
|
||||||
"getmaxmoney": true,
|
"getmaxmoney": true,
|
||||||
"getmaxvote": true,
|
"getmaxvote": true,
|
||||||
"getvote": true,
|
"getvote": true,
|
||||||
@@ -219,7 +219,8 @@ exports.public_api = {
|
|||||||
"getbalance": true,
|
"getbalance": true,
|
||||||
"getlasttxs": true,
|
"getlasttxs": true,
|
||||||
"getcurrentprice": true,
|
"getcurrentprice": true,
|
||||||
"getbasicstats": true
|
"getbasicstats": true,
|
||||||
|
"getmasternodelist": true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
var mongoose = require('mongoose')
|
||||||
|
, Schema = mongoose.Schema;
|
||||||
|
|
||||||
|
var MasternodeSchema = new Schema({
|
||||||
|
rank: { type: Number, default: 0 },
|
||||||
|
network: { type: String, default: "" },
|
||||||
|
txhash: { type: String, default: "" },
|
||||||
|
outidx : { type: Number, default: 0},
|
||||||
|
status : { type: String, default: "" },
|
||||||
|
addr: { type: String, unique: true, index: true },
|
||||||
|
version : { type: Number, default: 0},
|
||||||
|
lastseen: { type: Number, default: 0 },
|
||||||
|
activetime: { type: Number, default: 0 },
|
||||||
|
lastpaid: { type: Number, default: 0 },
|
||||||
|
claim_name: { type: String, default: '', index: true }
|
||||||
|
}, {id: false});
|
||||||
|
|
||||||
|
module.exports = mongoose.model('Masternode', MasternodeSchema);
|
||||||
+1
-2
@@ -5,13 +5,12 @@ var StatsSchema = new Schema({
|
|||||||
coin: { type: String },
|
coin: { type: String },
|
||||||
count: { type: Number, default: 1 },
|
count: { type: Number, default: 1 },
|
||||||
last: { type: Number, default: 1 },
|
last: { type: Number, default: 1 },
|
||||||
//difficulty: { type: Object, default: {} },
|
|
||||||
//hashrate: { type: String, default: 'N/A' },
|
|
||||||
supply: { type: Number, default: 0 },
|
supply: { type: Number, default: 0 },
|
||||||
txes: { type: Number, default: 0 },
|
txes: { type: Number, default: 0 },
|
||||||
connections: { type: Number, default: 0 },
|
connections: { type: Number, default: 0 },
|
||||||
last_price: { type: Number, default: 0 },
|
last_price: { type: Number, default: 0 },
|
||||||
last_usd_price: { type: Number, default: 0 },
|
last_usd_price: { type: Number, default: 0 },
|
||||||
|
masternodes_last_updated: { type: Number, default: 0 }
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = mongoose.model('coinstats', StatsSchema);
|
module.exports = mongoose.model('coinstats', StatsSchema);
|
||||||
@@ -465,7 +465,7 @@ table {
|
|||||||
padding-top: 15px !important;
|
padding-top: 15px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dataTables_length {
|
.dataTables_length, .dataTables_filter {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -255,6 +255,20 @@ router.get('/network', function(req, res) {
|
|||||||
res.render('network', {active: 'network', showSync: db.check_show_sync_message()});
|
res.render('network', {active: 'network', showSync: db.check_show_sync_message()});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// masternode list page
|
||||||
|
router.get('/masternodes', function(req, res) {
|
||||||
|
// ensure masternode page is enabled
|
||||||
|
if (settings.display.masternodes == true) {
|
||||||
|
// lookup last updated date
|
||||||
|
db.get_stats(settings.coin, function (stats) {
|
||||||
|
res.render('masternodes', {active: 'masternodes', last_updated: stats.masternodes_last_updated, showSync: db.check_show_sync_message()});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// masternode page is not enabled so default to the index page
|
||||||
|
route_get_index(res, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/reward', function(req, res) {
|
router.get('/reward', function(req, res) {
|
||||||
if (settings.heavy) {
|
if (settings.heavy) {
|
||||||
db.get_stats(settings.coin, function (stats) {
|
db.get_stats(settings.coin, function (stats) {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ db.heavies.remove({})
|
|||||||
db.heavies.drop()
|
db.heavies.drop()
|
||||||
db.markets.remove({})
|
db.markets.remove({})
|
||||||
db.markets.drop()
|
db.markets.drop()
|
||||||
|
db.masternodes.remove({})
|
||||||
|
db.masternodes.drop()
|
||||||
db.peers.remove({})
|
db.peers.remove({})
|
||||||
db.peers.drop()
|
db.peers.drop()
|
||||||
db.richlists.remove({})
|
db.richlists.remove({})
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ db.heavies.remove({})
|
|||||||
db.heavies.drop()
|
db.heavies.drop()
|
||||||
db.markets.remove({})
|
db.markets.remove({})
|
||||||
db.markets.drop()
|
db.markets.drop()
|
||||||
|
db.masternodes.remove({})
|
||||||
|
db.masternodes.drop()
|
||||||
db.peers.remove({})
|
db.peers.remove({})
|
||||||
db.peers.drop()
|
db.peers.drop()
|
||||||
db.richlists.remove({})
|
db.richlists.remove({})
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ function usage() {
|
|||||||
console.log('reindex-txcount Rescan and flatten the tx count value for faster access');
|
console.log('reindex-txcount Rescan and flatten the tx count value for faster access');
|
||||||
console.log('market Updates market summaries, orderbooks, trade history + charts');
|
console.log('market Updates market summaries, orderbooks, trade history + charts');
|
||||||
console.log('peers Updates peer info based on local wallet connections');
|
console.log('peers Updates peer info based on local wallet connections');
|
||||||
|
console.log('masternodes Updates the list of active masternodes on the network');
|
||||||
console.log('');
|
console.log('');
|
||||||
console.log('Notes:');
|
console.log('Notes:');
|
||||||
console.log('- \'current block\' is the latest created block when script is executed.');
|
console.log('- \'current block\' is the latest created block when script is executed.');
|
||||||
@@ -63,6 +64,8 @@ if (process.argv[2] == 'index') {
|
|||||||
database = 'market';
|
database = 'market';
|
||||||
} else if (process.argv[2] == 'peers') {
|
} else if (process.argv[2] == 'peers') {
|
||||||
database = 'peers';
|
database = 'peers';
|
||||||
|
} else if (process.argv[2] == 'masternodes') {
|
||||||
|
database = 'masternodes';
|
||||||
} else {
|
} else {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
@@ -236,6 +239,42 @@ if (database == 'peers') {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (database == 'masternodes') {
|
||||||
|
console.log('syncing masternodes.. please wait..');
|
||||||
|
// syncing masternodes does not require a lock
|
||||||
|
mongoose.connect(dbString, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true, useFindAndModify: false }, function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log('Unable to connect to database: %s', dbString);
|
||||||
|
console.log('Aborting');
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
lib.get_masternodelist(function (body) {
|
||||||
|
if (body != null) {
|
||||||
|
lib.syncLoop(body.length, function (loop) {
|
||||||
|
var i = loop.iteration();
|
||||||
|
db.save_masternode(body[i], function (success) {
|
||||||
|
if (success)
|
||||||
|
loop.next();
|
||||||
|
else {
|
||||||
|
console.log('error: cannot save masternode %s.', (body[i].addr ? body[i].addr : 'UNKNOWN'));
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
db.remove_old_masternodes(function (cb) {
|
||||||
|
db.update_last_updated_stats(settings.coin, { masternodes_last_updated: Math.floor(new Date() / 1000) }, function (cb) {
|
||||||
|
console.log('masternode sync complete');
|
||||||
|
exit();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('no masternodes found');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// index and market sync requires locking
|
// index and market sync requires locking
|
||||||
is_locked(function (exists) {
|
is_locked(function (exists) {
|
||||||
|
|||||||
+10
-2
@@ -34,6 +34,10 @@ if [ -n "${1}" ]; then
|
|||||||
# Peers update
|
# Peers update
|
||||||
MODE="peers"
|
MODE="peers"
|
||||||
;;
|
;;
|
||||||
|
"masternodes")
|
||||||
|
# Masternodes update
|
||||||
|
MODE="masternodes"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
# Check if this is a file that exists on the filesystem
|
# Check if this is a file that exists on the filesystem
|
||||||
if [ -f ${1} ]; then
|
if [ -f ${1} ]; then
|
||||||
@@ -75,7 +79,11 @@ if [ -n "${1}" ]; then
|
|||||||
"peers")
|
"peers")
|
||||||
# Peers update
|
# Peers update
|
||||||
MODE="peers"
|
MODE="peers"
|
||||||
;;
|
;;
|
||||||
|
"masternodes")
|
||||||
|
# Masternodes update
|
||||||
|
MODE="masternodes"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
elif [ -n "${NODE_PATH}" ]; then
|
elif [ -n "${NODE_PATH}" ]; then
|
||||||
# Node path was specified but no mode, so default to 'index update' mode
|
# Node path was specified but no mode, so default to 'index update' mode
|
||||||
@@ -90,7 +98,7 @@ fi
|
|||||||
if [ -n "${MODE}" ]; then
|
if [ -n "${MODE}" ]; then
|
||||||
# Mode is set
|
# Mode is set
|
||||||
# Check if the desired mode requires a lock
|
# Check if the desired mode requires a lock
|
||||||
if [ "${MODE}" != "peers" ]; then
|
if [ "${MODE}" != "peers" ] && [ "${MODE}" != "masternodes" ]; then
|
||||||
# A lock is required
|
# A lock is required
|
||||||
# Check if the script is already running (tmp/index.pid file already exists)
|
# Check if the script is already running (tmp/index.pid file already exists)
|
||||||
if [ -f "${EXPLORER_PATH}/tmp/index.pid" ]; then
|
if [ -f "${EXPLORER_PATH}/tmp/index.pid" ]; then
|
||||||
|
|||||||
@@ -115,6 +115,8 @@
|
|||||||
"search": true,
|
"search": true,
|
||||||
"movement": true,
|
"movement": true,
|
||||||
"network": true,
|
"network": true,
|
||||||
|
// Show/hide the "Masternodes" header menu item
|
||||||
|
"masternodes": true,
|
||||||
// Enable/disable the ability for users to claim a wallet address. NOTE: Disabling this feature after addresses have already been claimed will effectively hide the claimed values and restore the original wallet addresses again
|
// Enable/disable the ability for users to claim a wallet address. NOTE: Disabling this feature after addresses have already been claimed will effectively hide the claimed values and restore the original wallet addresses again
|
||||||
"claim_address": true,
|
"claim_address": true,
|
||||||
// Show/hide the "Claim Address" header menu item. NOTE: "claim_address" setting must also be enabled or else the header item will automatically be hidden as well
|
// Show/hide the "Claim Address" header menu item. NOTE: "claim_address" setting must also be enabled or else the header item will automatically be hidden as well
|
||||||
@@ -285,7 +287,6 @@
|
|||||||
"getnetworkhashps": true,
|
"getnetworkhashps": true,
|
||||||
"getvotelist": true,
|
"getvotelist": true,
|
||||||
"getmasternodecount": true,
|
"getmasternodecount": true,
|
||||||
"getmasternodelist": true,
|
|
||||||
"getmaxmoney": true,
|
"getmaxmoney": true,
|
||||||
"getmaxvote": true,
|
"getmaxvote": true,
|
||||||
"getvote": true,
|
"getvote": true,
|
||||||
@@ -303,7 +304,8 @@
|
|||||||
"getbalance": true,
|
"getbalance": true,
|
||||||
"getlasttxs": true,
|
"getlasttxs": true,
|
||||||
"getcurrentprice": true,
|
"getcurrentprice": true,
|
||||||
"getbasicstats": true
|
"getbasicstats": true,
|
||||||
|
"getmasternodelist": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -10,8 +10,8 @@ block content
|
|||||||
p
|
p
|
||||||
em #{settings.locale.api_message}
|
em #{settings.locale.api_message}
|
||||||
hr
|
hr
|
||||||
- var hide_rpc_api_section = !(settings.public_api.rpc['getdifficulty'] == true && settings.api_cmds['getdifficulty'] != null && settings.api_cmds['getdifficulty'] != '') && !(settings.public_api.rpc['getconnectioncount'] == true && settings.api_cmds['getconnectioncount'] != null && settings.api_cmds['getconnectioncount'] != '') && !(settings.public_api.rpc['getblockcount'] == true && settings.api_cmds['getblockcount'] != null && settings.api_cmds['getblockcount'] != '') && !(settings.public_api.rpc['getblockhash'] == true && settings.api_cmds['getblockhash'] != null && settings.api_cmds['getblockhash'] != '') && !(settings.public_api.rpc['getblock'] == true && settings.api_cmds['getblock'] != null && settings.api_cmds['getblock'] != '') && !(settings.public_api.rpc['getrawtransaction'] == true && settings.api_cmds['getrawtransaction'] != null && settings.api_cmds['getrawtransaction'] != '') && !(settings.public_api.rpc['getnetworkhashps'] == true && settings.index.show_hashrate == true && settings.api_cmds['getnetworkhashps'] != null && settings.api_cmds['getnetworkhashps'] != '') && !(settings.public_api.rpc['getvotelist'] == true && settings.api_cmds['getvotelist'] != null && settings.api_cmds['getvotelist'] != '') && !(settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '') && !(settings.public_api.rpc['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != '') && (!settings.heavy || (!(settings.public_api.rpc['getmaxmoney'] == true && settings.api_cmds.heavies['getmaxmoney'] != null && settings.api_cmds.heavies['getmaxmoney'] != '') && !(settings.public_api.rpc['getmaxvote'] == true && settings.api_cmds.heavies['getmaxvote'] != null && settings.api_cmds.heavies['getmaxvote'] != '') && !(settings.public_api.rpc['getvote'] == true && settings.api_cmds.heavies['getvote'] != null && settings.api_cmds.heavies['getvote'] != '') && !(settings.public_api.rpc['getphase'] == true && settings.api_cmds.heavies['getphase'] != null && settings.api_cmds.heavies['getphase'] != '') && !(settings.public_api.rpc['getreward'] == true && settings.api_cmds.heavies['getreward'] != null && settings.api_cmds.heavies['getreward'] != '') && !(settings.public_api.rpc['getsupply'] == true && settings.api_cmds.heavies['getsupply'] != null && settings.api_cmds.heavies['getsupply'] != '') && !(settings.public_api.rpc['getnextrewardestimate'] == true && settings.api_cmds.heavies['getnextrewardestimate'] != null && settings.api_cmds.heavies['getnextrewardestimate'] != '') && !(settings.public_api.rpc['getnextrewardwhenstr'] == true && settings.api_cmds.heavies['getnextrewardwhenstr'] != null && settings.api_cmds.heavies['getnextrewardwhenstr'] != '')));
|
- var hide_rpc_api_section = !(settings.public_api.rpc['getdifficulty'] == true && settings.api_cmds['getdifficulty'] != null && settings.api_cmds['getdifficulty'] != '') && !(settings.public_api.rpc['getconnectioncount'] == true && settings.api_cmds['getconnectioncount'] != null && settings.api_cmds['getconnectioncount'] != '') && !(settings.public_api.rpc['getblockcount'] == true && settings.api_cmds['getblockcount'] != null && settings.api_cmds['getblockcount'] != '') && !(settings.public_api.rpc['getblockhash'] == true && settings.api_cmds['getblockhash'] != null && settings.api_cmds['getblockhash'] != '') && !(settings.public_api.rpc['getblock'] == true && settings.api_cmds['getblock'] != null && settings.api_cmds['getblock'] != '') && !(settings.public_api.rpc['getrawtransaction'] == true && settings.api_cmds['getrawtransaction'] != null && settings.api_cmds['getrawtransaction'] != '') && !(settings.public_api.rpc['getnetworkhashps'] == true && settings.index.show_hashrate == true && settings.api_cmds['getnetworkhashps'] != null && settings.api_cmds['getnetworkhashps'] != '') && !(settings.public_api.rpc['getvotelist'] == true && settings.api_cmds['getvotelist'] != null && settings.api_cmds['getvotelist'] != '') && !(settings.public_api.rpc['getmasternodecount'] == true && settings.api_cmds['getmasternodecount'] != null && settings.api_cmds['getmasternodecount'] != '') && (!settings.heavy || (!(settings.public_api.rpc['getmaxmoney'] == true && settings.api_cmds.heavies['getmaxmoney'] != null && settings.api_cmds.heavies['getmaxmoney'] != '') && !(settings.public_api.rpc['getmaxvote'] == true && settings.api_cmds.heavies['getmaxvote'] != null && settings.api_cmds.heavies['getmaxvote'] != '') && !(settings.public_api.rpc['getvote'] == true && settings.api_cmds.heavies['getvote'] != null && settings.api_cmds.heavies['getvote'] != '') && !(settings.public_api.rpc['getphase'] == true && settings.api_cmds.heavies['getphase'] != null && settings.api_cmds.heavies['getphase'] != '') && !(settings.public_api.rpc['getreward'] == true && settings.api_cmds.heavies['getreward'] != null && settings.api_cmds.heavies['getreward'] != '') && !(settings.public_api.rpc['getsupply'] == true && settings.api_cmds.heavies['getsupply'] != null && settings.api_cmds.heavies['getsupply'] != '') && !(settings.public_api.rpc['getnextrewardestimate'] == true && settings.api_cmds.heavies['getnextrewardestimate'] != null && settings.api_cmds.heavies['getnextrewardestimate'] != '') && !(settings.public_api.rpc['getnextrewardwhenstr'] == true && settings.api_cmds.heavies['getnextrewardwhenstr'] != null && settings.api_cmds.heavies['getnextrewardwhenstr'] != '')));
|
||||||
- var hide_ext_api_section = !settings.public_api.ext['getmoneysupply'] && !settings.public_api.ext['getdistribution'] && !settings.public_api.ext['getaddress'] && !settings.public_api.ext['gettx'] && !settings.public_api.ext['getbalance'] && !settings.public_api.ext['getlasttxs'] && !settings.public_api.ext['getcurrentprice'] && !settings.public_api.ext['getbasicstats'];
|
- var hide_ext_api_section = !settings.public_api.ext['getmoneysupply'] && !settings.public_api.ext['getdistribution'] && !settings.public_api.ext['getaddress'] && !settings.public_api.ext['gettx'] && !settings.public_api.ext['getbalance'] && !settings.public_api.ext['getlasttxs'] && !settings.public_api.ext['getcurrentprice'] && !settings.public_api.ext['getbasicstats'] && !(settings.public_api.ext['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != '');
|
||||||
if !hide_rpc_api_section
|
if !hide_rpc_api_section
|
||||||
h3 #{settings.locale.api_calls}
|
h3 #{settings.locale.api_calls}
|
||||||
p
|
p
|
||||||
@@ -83,13 +83,6 @@ block content
|
|||||||
div
|
div
|
||||||
em #{settings.locale.api_getmasternodecount}
|
em #{settings.locale.api_getmasternodecount}
|
||||||
a(href='/api/getmasternodecount') #{address}/api/getmasternodecount
|
a(href='/api/getmasternodecount') #{address}/api/getmasternodecount
|
||||||
if settings.public_api.rpc['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != ''
|
|
||||||
li
|
|
||||||
p
|
|
||||||
div.font-weight-bold getmasternodelist
|
|
||||||
div
|
|
||||||
em #{settings.locale.api_getmasternodelist}
|
|
||||||
a(href='/api/getmasternodelist') #{address}/api/getmasternodelist
|
|
||||||
if settings.heavy == true
|
if settings.heavy == true
|
||||||
if settings.public_api.rpc['getmaxmoney'] == true && settings.api_cmds.heavies['getmaxmoney'] != null && settings.api_cmds.heavies['getmaxmoney'] != ''
|
if settings.public_api.rpc['getmaxmoney'] == true && settings.api_cmds.heavies['getmaxmoney'] != null && settings.api_cmds.heavies['getmaxmoney'] != ''
|
||||||
li
|
li
|
||||||
@@ -212,6 +205,13 @@ block content
|
|||||||
div
|
div
|
||||||
em Returns basic statistics about the coin including: block count, circulating supply, USD price, BTC price and # of masternodes
|
em Returns basic statistics about the coin including: block count, circulating supply, USD price, BTC price and # of masternodes
|
||||||
a(href='/ext/getbasicstats') #{address}/ext/getbasicstats
|
a(href='/ext/getbasicstats') #{address}/ext/getbasicstats
|
||||||
|
if settings.public_api.ext['getmasternodelist'] == true && settings.api_cmds['getmasternodelist'] != null && settings.api_cmds['getmasternodelist'] != ''
|
||||||
|
li
|
||||||
|
p
|
||||||
|
div.font-weight-bold getmasternodelist
|
||||||
|
div
|
||||||
|
em #{settings.locale.api_getmasternodelist}
|
||||||
|
a(href='/ext/getmasternodelist') #{address}/ext/getmasternodelist
|
||||||
hr
|
hr
|
||||||
h3 Linking (GET)
|
h3 Linking (GET)
|
||||||
p
|
p
|
||||||
|
|||||||
+6
-1
@@ -324,6 +324,11 @@ html(lang='en')
|
|||||||
a.nav-link(href='/reward')
|
a.nav-link(href='/reward')
|
||||||
span.fa.fa-star
|
span.fa.fa-star
|
||||||
span.margin-left-5 #{settings.locale.menu_reward}
|
span.margin-left-5 #{settings.locale.menu_reward}
|
||||||
|
if settings.display.masternodes == true
|
||||||
|
li#masternodes
|
||||||
|
a.nav-link(href='/masternodes')
|
||||||
|
span.fa.fa-share-alt
|
||||||
|
span.margin-left-5 Masternodes
|
||||||
if settings.display.movement == true
|
if settings.display.movement == true
|
||||||
li#movement
|
li#movement
|
||||||
a.nav-link.loading(href='/movement')
|
a.nav-link.loading(href='/movement')
|
||||||
@@ -332,7 +337,7 @@ html(lang='en')
|
|||||||
if settings.display.network == true
|
if settings.display.network == true
|
||||||
li#network
|
li#network
|
||||||
a.nav-link(href='/network')
|
a.nav-link(href='/network')
|
||||||
span.fa.fa-share-alt
|
span.fas.fa-network-wired
|
||||||
span.margin-left-5 #{settings.locale.menu_network}
|
span.margin-left-5 #{settings.locale.menu_network}
|
||||||
if settings.display.richlist == true
|
if settings.display.richlist == true
|
||||||
li#richlist
|
li#richlist
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
extends layout
|
||||||
|
|
||||||
|
block content
|
||||||
|
include ./includes/common.pug
|
||||||
|
script.
|
||||||
|
function secondsToHms(d) {
|
||||||
|
d = Number(d);
|
||||||
|
var h = Math.floor(d / 3600);
|
||||||
|
var m = Math.floor(d % 3600 / 60);
|
||||||
|
var s = Math.floor(d % 3600 % 60);
|
||||||
|
var dy = Math.floor(h / 24);
|
||||||
|
var h = h % 24;
|
||||||
|
return ('0' + dy).slice(-2) + " day" + (('0' + dy).slice(-2) == 1 ? "" : "s") + " " + ('0' + h).slice(-2) + "h " + ('0' + m).slice(-2) + "m " + ('0' + s).slice(-2) + "s";
|
||||||
|
}
|
||||||
|
$(document).ready(function() {
|
||||||
|
var labels = !{JSON.stringify(settings.labels)};
|
||||||
|
var ctable = $('#masternodes-table').dataTable({
|
||||||
|
autoWidth: true,
|
||||||
|
searching: true,
|
||||||
|
ordering: true,
|
||||||
|
order: [[ 5, 'desc' ]],
|
||||||
|
responsive: true,
|
||||||
|
lengthChange: true,
|
||||||
|
processing: true,
|
||||||
|
scrollX: true,
|
||||||
|
language: {
|
||||||
|
paginate: {
|
||||||
|
previous: '<',
|
||||||
|
next: '>'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ajax: {
|
||||||
|
url: '/ext/getmasternodelist',
|
||||||
|
dataSrc: function(json) {
|
||||||
|
for (i = 0; i < json.length; i++) {
|
||||||
|
var addr = json[i]['addr'];
|
||||||
|
json[i]['address'] = "<a href='/address/" + json[i]['address'] + "'>" + json[i]['address'] + "</a>";
|
||||||
|
json[i]['lastseen'] = new Date((json[i]['lastseen']) * 1000).toLocaleString();
|
||||||
|
if (typeof json[i]['lastpaid'] != 'undefined')
|
||||||
|
json[i]['lastpaid'] = new Date((json[i]['lastpaid']) * 1000).toLocaleString();
|
||||||
|
else
|
||||||
|
json[i]['lastpaid'] = '<em>N/A</em>';
|
||||||
|
if (json[i]['activetime'])
|
||||||
|
json[i]['activetime'] = secondsToHms(json[i]['activetime']);
|
||||||
|
else
|
||||||
|
json[i]['activetime'] = '<em>N/A</em>';
|
||||||
|
json[i]['addr'] = "<a href='/address/" + json[i]['addr'] + "'>" + json[i]['addr'] + (json[i]['claim_name'] != null && json[i]['claim_name'] != '' ? ' <span class="small">(' + json[i]['claim_name'] + ')</span>' : '') + "</a>";
|
||||||
|
|
||||||
|
if (labels[addr] != null) {
|
||||||
|
if (labels[addr].type)
|
||||||
|
json[i]['addr'] = '<div><label class="badge badge-' + labels[addr].type + '" style="margin-bottom:10px;">' + labels[addr].label + (labels[addr].url ? '<a href="' + labels[addr].url + '" target="_blank", alt="Visit site", title="Visit site" data-toggle="tooltip" data-placement="top"><span class="fa fa-question-circle" style="margin-left:5px"></span></a>' : '') + '</label></div>' + json[i]['addr'];
|
||||||
|
else
|
||||||
|
json[i]['addr'] = '<div><label class="badge badge-default" style="margin-bottom:10px;">' + labels[addr].label + (labels[addr].url ? '<a href="' + labels[addr].url + '" target="_blank", alt="Visit site", title="Visit site" data-toggle="tooltip" data-placement="top"><span class="fa fa-question-circle" style="margin-left:5px"></span></a>' : '') + '</label></div>' + json[i]['addr'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: 'rank' },
|
||||||
|
{ data: 'network' },
|
||||||
|
{ data: 'addr' },
|
||||||
|
{ data: 'version' },
|
||||||
|
{ data: 'lastseen' },
|
||||||
|
{ data: 'lastpaid' },
|
||||||
|
{ data: 'activetime' },
|
||||||
|
{ data: 'status' }
|
||||||
|
],
|
||||||
|
rowCallback: function(row, data, index) {
|
||||||
|
$("td:eq(2)", row).addClass("breakWord");
|
||||||
|
|
||||||
|
switch (data['status'].toUpperCase()) {
|
||||||
|
case 'ENABLED':
|
||||||
|
$("td:eq(7)", row).addClass('bg-success');
|
||||||
|
break;
|
||||||
|
case 'REMOVE':
|
||||||
|
$("td:eq(7)", row).addClass('bg-danger');
|
||||||
|
break;
|
||||||
|
case 'EXPIRED':
|
||||||
|
$("td:eq(7)", row).addClass('bg-warning');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$("td:eq(7)", row).addClass('bg-info');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fnDrawCallback: function(settings) {
|
||||||
|
fixDataTableColumns();
|
||||||
|
fixFooterHeightAndPosition();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
.col-md-12.cardSpacer
|
||||||
|
.text-center(style='margin-bottom:15px;')
|
||||||
|
i The current listing of all masternodes known to be active on the network.
|
||||||
|
div.font-weight-bold(style='margin-bottom:15px;') Last updated:
|
||||||
|
span.font-weight-normal=(last_updated == null ? ' N/A' : ' ' + format_unixtime(last_updated))
|
||||||
|
.card.card-default
|
||||||
|
.card-header
|
||||||
|
strong Masternodes
|
||||||
|
table#masternodes-table.table.table-bordered.table-striped.table-hover
|
||||||
|
- var theadClasses = [];
|
||||||
|
if settings.display.table_header_bgcolor != null && settings.display.table_header_bgcolor != ''
|
||||||
|
- theadClasses.push('thead-' + settings.display.table_header_bgcolor);
|
||||||
|
thead(class=theadClasses)
|
||||||
|
tr
|
||||||
|
th.text-center Pay rank
|
||||||
|
th.text-center Protocol
|
||||||
|
th.text-center Address
|
||||||
|
th.text-center Protocol
|
||||||
|
th.text-center Last seen
|
||||||
|
th.text-center Last paid
|
||||||
|
th.text-center Active since
|
||||||
|
th.text-center Status
|
||||||
|
tbody.text-center
|
||||||
Reference in New Issue
Block a user