diff --git a/app.js b/app.js index dcc2f258b..1ce12475f 100644 --- a/app.js +++ b/app.js @@ -1,60 +1,24 @@ const express = require('express'), debug = require('debug')('explorer'), path = require('path'), - bitcoinapi = require('bitcoin-node-api'), + { api } = require('./lib/api'), favicon = require('static-favicon'), logger = require('morgan'), cookieParser = require('cookie-parser'), bodyParser = require('body-parser'), - request = require('request'), settings = require('./lib/settings'), routes = require('./routes/index'), lib = require('./lib/explorer'), db = require('./lib/database'), locale = require('./lib/locale'), - { promisify, spawnCmd, requestp } = require('./lib/util') - -const app = express(); - -// set database update intervals -spawnCmd('node', [ 'scripts/sync.js', 'index', settings.index.index_mode || 'update' ]) -setInterval(function () { - spawnCmd('node', [ 'scripts/sync.js', 'index', 'update' ]) -}, settings.sync_timeout) -setInterval(function () { - spawnCmd('node', [ 'scripts/sync.js', 'market' ]) -}, settings.market_timeout) -setInterval(function () { - spawnCmd('node', [ 'scripts/peers.js' ]) -}, settings.peer_timeout) - -const info = require('./info'); + { requestp } = require('./lib/util'), + info = require('./info') + +const app = express() info(app) +api.setCachers(db.rpc) -// bitcoinapi -bitcoinapi.setWalletDetails(settings.wallet); -if (settings.heavy != true) { - bitcoinapi.setAccess('only', [ 'getinfo', 'getnetworkhashps', 'getmininginfo','getdifficulty', 'getconnectioncount', - 'getblockcount', 'getblockhash', 'getblock', 'getrawtransaction', 'getpeerinfo', 'gettxoutsetinfo', 'getmempoolinfo', 'getrawmempool' ]); -} else { - // enable additional heavy api calls - /* - getvote - Returns the current block reward vote setting. - getmaxvote - Returns the maximum allowed vote for the current phase of voting. - getphase - Returns the current voting phase ('Mint', 'Limit' or 'Sustain'). - getreward - Returns the current block reward, which has been decided democratically in the previous round of block reward voting. - getnextrewardestimate - Returns an estimate for the next block reward based on the current state of decentralized voting. - getnextrewardwhenstr - Returns string describing how long until the votes are tallied and the next block reward is computed. - getnextrewardwhensec - Same as above, but returns integer seconds. - getsupply - Returns the current money supply. - getmaxmoney - Returns the maximum possible money supply. - */ - bitcoinapi.setAccess('only', [ 'getinfo', 'getstakinginfo', 'getnetworkhashps', 'getdifficulty', 'getconnectioncount', - 'getblockcount', 'getblockhash', 'getblock', 'getrawtransaction','getmaxmoney', 'getvote', - 'getmaxvote', 'getphase', 'getreward', 'getnextrewardestimate', 'getnextrewardwhenstr', - 'getnextrewardwhensec', 'getsupply', 'gettxoutsetinfo', 'getmempoolinfo', 'getrawmempool' ]); -} -// view engine setup + // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); @@ -66,7 +30,7 @@ app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); // routes -app.use('/api', bitcoinapi.app); +app.use('/api', api.app); app.use('/', routes); app.use('/ext/getmoneysupply', function(req,res){ lib.get_supply(function(supply){ @@ -111,74 +75,35 @@ app.use('/ext/getdistribution', function(req,res){ }); }); -app.use('/ext/getlasttxs', function (req, res) { - return db.get_last_txs(parseInt(req.query.count), req.query.minAmount * 100000000, req.query.start).then(txs => - res.send({data: txs}) - ).catch(err => { - debug(err) - res.send({ error: `An error occurred: ${err}` }) - }) -}); - -app.use('/ext/getblocks/:start/:end', function (req, res) { +app.use('/ext/getblocks/:start/:end', async function (req, res) { const endpoint = settings.address || `http://${req.headers.host}` const start = parseInt(req.param('start')) const end = parseInt(req.param('end')) const reverse = req.query.reverse && req.query.reverse.toLowerCase() === 'true' - const strip = req.query.strip && req.query.strip.toLowerCase() === 'true' + const flds = typeof req.query.flds === 'string' ? req.query.flds.split(',') : req.query.flds || [] if (start > end) { res.send({ error: `End blockheight must be greater than or equal to the start blockheight.` }) return } + const blockcount = await requestp(`${endpoint}/api/getblockcount`) let heights = Array(end - start + 1).fill(undefined).map((_, i) => start + i) - const txReq = () => Promise.all(heights.map(i => - db.getTxs({ height: i }).then(txs => { - // sorts transactions from newest to oldest - txs.sort((a, b) => { - if (a.blockindex !== b.blockindex) return a.blockindex > b.blockindex ? -1 : 1 - if (a.timestamp !== b.timestamp) return a.timestamp > b.timestamp ? -1 : 1 - return a._id > b._id ? -1 : 1 - }) - // since reverse means to go from newest to oldest - return reverse ? txs : txs.reverse() - }) - )) - const infoReq = (blockcount) => Promise.all(heights.map(i => - promisify(lib.get_blockhash, i) - .then(hash => - hash.includes('There was an error') ? null : lib.getBlock(hash, undefined, blockcount) - ) - )).then(infos => strip ? infos.filter(info => info !== null) : infos) - const onErr = err => { - debug(err) - res.send({ error: `An error occurred: ${err}` }) + if (reverse) heights = heights.map(h => blockcount - h + 1) + + const searchFlds = flds[0] === 'summary' + ? { fulltx: 0, _id: 0 } + : flds ? flds.reduce((acc, fld) => ({ ...acc, [fld]: 1 }), { _id: 0, height: 1 }) : [] + let blocks = await db.getBlocks(heights, searchFlds) + if (!blocks) { + blocks = await Promise.all(heights.map(h => lib.getRawRpc('getblockhash', [ h ]).then(hash => lib.getRawRpc('getblock', [ hash ])))) + } else { + blocks = blocks.sort((a, b) => (reverse ? -1 : 1) * (a.height <= b.height ? -1 : 1)) } - - promisify(request, `${endpoint}/api/getblockcount`, { json: true }).then(([ err, resp, height ]) => { - if (reverse) heights = heights.map(h => height - h + 1) - return height - }).then(blockcount => { - if (req.query.flds === 'summary') { - infoReq(blockcount).then(infos => res.send({ data: { blockcount, blocks: infos } })).catch(onErr) - } else if (req.query.flds && req.query.flds.length === 1 && req.query.flds[0] === 'tx') { - txReq().then(txs => res.send({ data: { blockcount, blocks: txs } })).catch(onErr) - } else { - Promise.all([ txReq(), infoReq(blockcount) ]).then(([ txs, infos ]) => { - res.send({ - data: { blockcount, blocks: infos.map((info, i) => ({ ...info, tx: txs[i] })).map(block => { - if (req.query.flds && req.query.flds.length) { - Object.keys(block).forEach(key => { - if (!req.query.flds.includes(key)) delete block[key] - }) - } - return block - }) } - }) - }).catch(onErr) - } - }).catch(onErr) + blocks.forEach(block => { + if (!flds.includes('height') && flds[0] !== 'summary') delete block['height'] + }) + res.send({ data: { blockcount, blocks } }) }) app.use('/ext/connections', function(req,res){ @@ -200,7 +125,6 @@ app.set('googleplus', settings.googleplus); app.set('youtube', settings.youtube); app.set('genesis_block', settings.genesis_block); app.set('index', settings.index); -app.set('heavy', settings.heavy); app.set('txcount', settings.txcount); app.set('nethash', settings.nethash); app.set('nethash_units', settings.nethash_units); diff --git a/bin/cluster.js b/bin/cluster.js index 61c1aeb92..54fef3f42 100644 --- a/bin/cluster.js +++ b/bin/cluster.js @@ -3,7 +3,7 @@ const cluster = require('cluster') const fs = require('fs') const settings = require('../lib/settings') const db = require('../lib/database') -const { prettyPrint } = require('../lib/util') +const { prettyPrint, spawnCmd } = require('../lib/util') if (cluster.isMaster) { fs.writeFile('./tmp/cluster.pid', process.pid, function (err) { @@ -12,6 +12,9 @@ if (cluster.isMaster) { process.exit(1) } else { debug('Starting cluster with pid: ' + process.pid) + + const updateIntervals = [] + // ensure workers exit cleanly process.on('SIGINT', () => { debug('Cluster shutting down...') @@ -19,6 +22,7 @@ if (cluster.isMaster) { worker.kill() } // exit the master process + // updateIntervals.forEach(i => clearInterval(i)) process.exit(0) }) @@ -26,6 +30,18 @@ if (cluster.isMaster) { db.connect(settings.dbsettings).then(() => db.setupSchema() ).then(() => { + // set database update intervals + spawnCmd('node', [ 'scripts/sync.js', 'index', settings.index.index_mode || 'update' ]) + updateIntervals.push(setInterval(function () { + spawnCmd('node', [ 'scripts/sync.js', 'index', 'update' ]) + }, settings.sync_timeout)) + updateIntervals.push(setInterval(function () { + spawnCmd('node', [ 'scripts/sync.js', 'market' ]) + }, settings.market_timeout)) + updateIntervals.push(setInterval(function () { + spawnCmd('node', [ 'scripts/peers.js' ]) + }, settings.peer_timeout)) + // spawn a worker for each cpu core require('os').cpus().forEach(_ => { cluster.fork() @@ -33,6 +49,7 @@ if (cluster.isMaster) { }).catch(err => { debug(`An error occured setting up cluster: ${prettyPrint(err)}`) debug('Aborting...') + // updateIntervals.forEach(i => clearInterval(i)) process.exit(1) }) diff --git a/bin/instance.js b/bin/instance.js index 477114613..1f7d69558 100755 --- a/bin/instance.js +++ b/bin/instance.js @@ -1,6 +1,9 @@ #!/usr/bin/env node -const debug = require('debug')('explorer') + +// ensure the api singleton has been initialized before anything else const settings = require('../lib/settings') + +const debug = require('debug')('explorer') const db = require('../lib/database') const app = require('../app') const { promisify } = require('../lib/util') @@ -9,9 +12,11 @@ app.set('port', process.env.PORT || settings.port) db.connect(settings.dbsettings).then(() => promisify(db.get_stats, settings.coin) -).then((stats) => { +).then(stats => { app.locals.stats = stats const server = app.listen(app.get('port'), () => { debug('Express server listening on port ' + server.address().port) }) +}).catch(err => { + process.exit(1) }) diff --git a/config/default.json b/config/default.json index 67a682bfd..42387b321 100644 --- a/config/default.json +++ b/config/default.json @@ -1,14 +1,19 @@ { "dbsettings": { "uri": "mongodb://localhost:27017/blockchain-explorer", - "options": { "useNewUrlParser": true }, + "options": { "useNewUrlParser": true, "autoIndex": false }, "benchmark_uri": "mongodb://localhost:27017/explorer-benchmark", "benchmark_options": { "useNewUrlParser": true } }, "wallet": { "url": "http://localhost:18332", "username": "undefined", - "password": "undefined" + "password": "undefined", + "network": "testnet", + "ssl": { + "enabled": false, + "strict": false + } }, "title": "Equibit", "address": "http://127.0.0.1:3001", @@ -23,6 +28,7 @@ "sync_timeout": 60000, "market_timeout": 120000, "peer_timeout": 240000, + "ui_interval": 30000, "confirmations": 40, "locale": "locale/en.json", "display": { @@ -72,7 +78,6 @@ "youtube": "UCBWEY89pt-DpPYyPedqGWEg", "genesis_tx": "ea914133c255e8b47fb99d26b8627f90e12f5a9c3bc86269652d474d9814aaca", "genesis_block": "0000e9b3a79f70fb0be95b38604636441323450731e9ee1b5ef410791dac7184", - "heavy": false, "txcount": 100, "show_sent_received": true, "supply": "COINBASE", diff --git a/lib/api.js b/lib/api.js new file mode 100644 index 000000000..fc8190390 --- /dev/null +++ b/lib/api.js @@ -0,0 +1,146 @@ +const express = require('express') +const debug = require('debug')('explorer:api') +const Client = require('bitcoin-core') +const settings = require('./settings') + +const SpecTypes = Object.freeze({ 'ALL': 0, 'ONLY': 1, 'EXCEPT': 2 }) +const CacheTypes = Object.freeze({ 'FORCE': 0, 'NEVER': 1, 'AS_NEEDED': 2 }) + +class Api { + + constructor ({ + rpcConfig = { + type: SpecTypes.ALL, + cacheDefault: CacheTypes.FORCE, + allowRaw: false, + rpc: [] + }, + cachers, + wallet = {} + }) { + this.app = express() + this.rpcConfig = rpcConfig + this.cachers = cachers + this.setWalletDetails(wallet) + + this.app.get('*', this.hasAccess.bind(this), (req, res) => { + const method = req.path.substr(1) + if (Api.requiresCredentials.includes(method) && !this.client.password) { + return res.send('A wallet password is required and has not been set.') + } + const parameters = (req.query instanceof Array ? req.query : Object.values(req.query)).map(param => isNaN(param) ? param : parseFloat(param)) + + switch (this.getCacheType(method)) { + case CacheTypes.FORCE: + return this.cachers.hasOwnProperty(method) + ? this.cachers[method](...parameters).then(this.handle).then(resp => res.send(resp)) + : res.send(`No caching method was supplied for ${method}.`) + case CacheTypes.NEVER: + return res.send(this.rawRpc(method, parameters)) + case CacheTypes.AS_NEEDED: + if (!this.cachers.hasOwnProperty(method)) return res.send(this.rawRpc(method, parameters)) + return this.cachers[method](...parameters).then(this.handle).then(resp => resp === 'There was an error.' + ? this.rawRpc(method, parameters) + : resp + ).then(resp => res.send(resp)) + } + }) + } + + async rawRpc (method, parameters) { + return this.client.command([ { method, parameters } ]).then(([ resp, err ]) => this.handle(resp, err)) + } + + async callRawRpc (method, parameters) { + return this.rpcConfig.allowRaw ? this.rawRpc(method, parameters) : 'Direct RPC calls are not enabled.' + } + + getCacheType (method) { + if (this.rpcConfig.type === SpecTypes.ONLY) { + return Object.values(CacheTypes).includes(this.rpcConfig.rpc[method]) + ? this.rpcConfig.rpc[method] + : this.rpcConfig.cacheDefault + } + return this.rpcConfig.cacheDefault + } + + handle (success, fail) { + + return (data) => { + if (data instanceof Error) { + console.log(err) + return 'There was an error.' + } + // if its an object just send it as is, otherwise cast to string + return (data instanceof Object) ? data : (''+data) + } + } + + hasAccess (req, res, next) { + if (this.rpcConfig.type === SpecTypes.ALL) return next() + + const method = req.path.substr(1) + if ( + (this.rpcConfig.type === SpecTypes.ONLY && this.rpcConfig.rpc.includes(method)) + || (this.rpcConfig.type === SpecTypes.EXCEPT && !this.rpcConfig.rpc.includes(method)) + ) { + return next() + } else { + res.end('This method is restricted') + } + } + + setWalletDetails (details) { + this.walletDetails = details + this.client = new Client(details) + } + + setCachers (cachers) { + this.cachers = cachers + } + + static get requiresCredentials () { + return [ + 'dumpprivkey', + 'importprivkey', + 'keypoolrefill', + 'sendfrom', + 'sendmany', + 'sendtoaddress', + 'signmessage', + 'signrawtransaction' + ] + } + +} + +function api () { + return new Api({ + rpcConfig: { + type: SpecTypes.ONLY, + cacheDefault: CacheTypes.NEVER, + allowRaw: true, + rpc: [ + 'getnetworkhashps', + 'getmininginfo', + 'getdifficulty', + 'getconnectioncount', + 'getblockcount', + 'getblockhash', + 'getblock', + 'getrawtransaction', + 'getpeerinfo', + 'gettxoutsetinfo', + 'getmempoolinfo', + 'getrawmempool' + ] + }, + wallet: settings.wallet + }) +} + +module.exports = { + api: api(), + SpecTypes, + CacheTypes +} diff --git a/lib/database.js b/lib/database.js index 30cf7076d..e46064b93 100644 --- a/lib/database.js +++ b/lib/database.js @@ -4,11 +4,8 @@ const mongoose = require('mongoose'), Markets = require('../models/markets'), Address = require('../models/address'), Block = require('../models/block'), - Tx = require('../models/tx'), Richlist = require('../models/richlist'), Peers = require('../models/peers'), - Heavy = require('../models/heavy'), - lib = require('./explorer'), settings = require('./settings'), poloniex = require('./markets/poloniex'), bittrex = require('./markets/bittrex'), @@ -18,7 +15,8 @@ const mongoose = require('mongoose'), yobit = require('./markets/yobit'), empoex = require('./markets/empoex'), ccex = require('./markets/ccex'), - { promisify, prettyPrint } = require('../lib/util') + lib = require('./explorer'), + { promisify, prettyPrint, renameProp, wait } = require('./util') function find_address(hash, cb) { Address.findOne({a_id: hash}, function(err, address) { @@ -123,67 +121,29 @@ function update_address(hash, txid, amount, type, cb) { }); } -function findTx (txid) { - return new Promise((resolve, reject) => Tx.findOne({txid: txid}, (err, tx) => { - if (err) reject(err) - else resolve(tx) - })) +async function findTx (txid) { + const [ err, block ] = await promisify(Block.findOne.bind(Block), { tx: txid }) + if (err) throw new Error(err) + else return parseTx(block, txid) } -function save_tx(txid, cb) { - lib.get_rawtransaction(txid, function(tx){ - if (tx != 'There was an error. Check your console.') { - lib.getBlock(tx.blockhash, function (block) { - if (block) { - lib.prepare_vin(tx, function(vin) { - lib.prepare_vout(tx.vout, txid, vin, function(vout, nvin) { - lib.syncLoop(vin.length, function (loop) { - var i = loop.iteration(); - update_address(nvin[i].addresses, txid, nvin[i].amount, 'vin', function(){ - loop.next(); - }); - }, function(){ - lib.syncLoop(vout.length, function (subloop) { - var t = subloop.iteration(); - if (vout[t].addresses) { - update_address(vout[t].addresses, txid, vout[t].amount, 'vout', function(){ - subloop.next(); - }); - } else { - subloop.next(); - } - }, function(){ - lib.calculate_total(vout, function(total){ - var newTx = new Tx({ - txid: tx.txid, - vin: nvin, - vout: vout, - total: total.toFixed(8), - timestamp: tx.time, - blockhash: tx.blockhash, - blockindex: block.height, - }); - newTx.save(function(err) { - if (err) { - return cb(err); - } else { - //console.log('txid: '); - return cb(); - } - }); - }); - }); - }); - }); - }); - } else { - return cb('block not found: ' + tx.blockhash); - } - }); - } else { - return cb('tx not found: ' + txid); - } - }); +async function parseTx(block, i) { + const tx = i instanceof Object ? i : /[a-z]/i.test(i) ? block.fulltx.find(tx => tx.txid === i) : block.fulltx[i] + const [ vout, vin ] = await lib.prepare_vin(tx).then(vin => promisify(lib.prepare_vout, tx.vout, tx.txid, vin)) + for (const v of vin) await promisify(update_address, v.addresses, tx.txid, v.amount, 'vin') + for (const v of vout) { + if (v.addresses) await promisify(update_address, v.addresses, tx.txid, v.amount, 'vout') + } + const total = await promisify(lib.calculate_total, vout) + return { + txid: tx.txid, + vin, + vout, + total, + timestamp: tx.time, + blockhash: block.hash, + blockindex: block.height + } } function get_market_data(market, cb) { @@ -233,13 +193,127 @@ function get_market_data(market, cb) { } } +function dbToRpcBlock (block, blockcount, include) { + return Object.entries({ + confirmations: block.height ? blockcount - block.height : undefined, + strippedsize: block.size, + versionHex: block.version ? block.version.toString(16) : undefined, + nTx: block.tx ? block.tx.length : undefined + }) + .filter(([ key, value ]) => value !== undefined && (!include || include.includes(key))) + .reduce((acc, [ key, value ]) => ({ ...acc, [key]: value }), { ...block }) +} + +const rpcOnError = (method, err) => { + debug(`An error occurred while trying access cache of ${method}: ${err}`) + return new Error(`Caching ${method} resulted in: ${err}`) +} +const rpc = { + + getnetworkhashps () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { networkhashps: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getnetworkhashps', err) + return res.networkhashps + }) + }, + + getmininginfo () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getmininginfo', err) + return res + }) + }, + + getdifficulty () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { difficulty: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getdifficulty', err) + return res.difficulty + }) + }, + + getconnectioncount () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { connections: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getconnectioncount', err) + return res.connections + }) + }, + + getblockcount () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { blocks: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getdifficulty', err) + return res.blocks + }) + }, + + getblockhash (height) { + return promisify(Block.findOne.bind(Block), { height }, { hash: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getblockhash', err) + return res.hash + }) + }, + + async getblock (hash) { + const blockcount = await promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { blocks: 1, _id: 0 }).then(([ err, stats ]) => { + if (err) return rpcOnError('getblock', err) + return stats.blocks + }) + return promisify(Block.findOne.bind(Block), { hash }, { fulltx: 0, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getblock', err) + return dbToRpcBlock(res._doc, blockcount) + }) + }, + + getrawtransaction (txid, format) { + return promisify(Block.findOne.bind(Block), { fulltx: { $elemMatch: { txid } } }, { fulltx: 1, _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getrawtransaction', err) + const tx = res.fulltx.find(tx => tx.txid === txid) + return format ? tx : tx.hex + }) + }, + + getpeerinfo () { + return promisify(Peers.find.bind(Peers), {}, { _id: 0 }).then(([ err, res ]) => { + if (err) return rpcOnError('getpeerinfo', err) + return res + }) + }, + + gettxoutsetinfo () { + return promisify(Stats.findOne.bind(Stats), { coin: settings.coin }, { + blocks: 1, + bestblock: 1, + transactions: 1, + txouts: 1, + bogosize: 1, + hash_serialized_2: 1, + disk_size: 1, + supply: 1, + _id: 0 + }).then(([ err, res ]) => { + if (err) return rpcOnError('getdifficulty', err) + return renameProp('supply', 'total_amount', renameProp('blocks', 'height', res)) + }) + }, + + getmempoolinfo () { + + }, + + getrawmempool () { + + } + +} + module.exports = { + rpc, + connect (dbSettings) { - return mongoose.connect(dbSettings.uri, dbSettings.options).catch(err => { + return promisify(mongoose.connect, dbSettings.uri, dbSettings.options).catch(err => { console.log(`Unable to connect to database: ${dbSettings.uri}`); console.log(`With options: ${prettyPrint(dbSettings.options, null, 2)}`); console.log(`Aborting with ERROR: ${prettyPrint(err)}`) - process.exit(1); + throw new Error(err) }); }, @@ -312,70 +386,15 @@ module.exports = { } }, - get_tx (txid, cb) { - findTx(txid).then(tx => { - return cb(tx) - }) - }, - - getTxs (block) { - return new Promise((resolve, reject) => { - if (block.tx && block.tx.length) { - Promise.all(block.tx.map(tx => findTx(tx))) - .then(txs => resolve(txs)) - .catch(err => reject(err)) - } else if (block.hash) { - Tx.find({ 'blockhash': block.hash }, (err, res) => { - if (err) reject(err) - else resolve(res) - }) - } else if (block.height) { - Tx.find({ 'blockindex': block.height }, (err, res) => { - if (err) reject(err) - else resolve(res) - }) - } - - }) - }, - - create_tx: function(txid, cb) { - save_tx(txid, function(err){ - if (err) { - return cb(err); - } else { - //console.log('tx stored: %s', txid); - return cb(); - } - }); - }, - - create_txs: function(block, cb) { - lib.syncLoop(block.tx.length, function (loop) { - var i = loop.iteration(); - save_tx(block.tx[i], function(err){ - if (err) { - loop.next(); - } else { - //console.log('tx stored: %s', block.tx[i]); - loop.next(); - } - }); - }, function(){ - return cb(); - }); + async get_tx (txid, cb) { + const tx = await findTx(txid) + return cb ? cb(await tx) : tx }, - get_last_txs (count, minAmount, start) { - return new Promise((resolve, reject) => { - Tx.find(Object.assign({ 'total': { $gt: minAmount } }, start ? { '_id': { $lt: start } } : {} )) - .sort({ '_id': 'desc' }) - .limit(count) - .exec((err, txs) => { - if (err) reject(err) - else resolve(txs) - }) - }) + async getTxs (block) { + return promisify(Block.findOne.bind(Block), block).then(([ err, block ]) => + err || !block ? null : Promise.all(block.tx.map(tx => parseTx(block, tx))) + ) }, create_market: function(coin, exchange, market, cb) { @@ -446,41 +465,6 @@ module.exports = { }); }, - create_heavy: function(coin, cb) { - var newHeavy = new Heavy({ - coin: coin, - }); - newHeavy.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else { - console.log("initial heavy entry created for %s", coin); - console.log(newHeavy); - return cb(); - } - }); - }, - - check_heavy: function(coin, cb) { - Heavy.findOne({coin: coin}, function(err, exists) { - if(exists) { - return cb(true); - } else { - return cb(false); - } - }); - }, - - get_heavy: function(coin, cb) { - Heavy.findOne({coin: coin}, function(err, heavy) { - if(heavy) { - return cb(heavy); - } else { - return cb(null); - } - }); - }, get_distribution: function(richlist, stats, cb){ var distribution = { supply: stats.supply, @@ -525,52 +509,6 @@ module.exports = { return cb(distribution); }); }, - // updates heavy stats for coin - // height: current block height, count: amount of votes to store - update_heavy: function(coin, height, count, cb) { - var newVotes = []; - lib.get_maxmoney( function (maxmoney) { - lib.get_maxvote( function (maxvote) { - lib.get_vote( function (vote) { - lib.get_phase( function (phase) { - lib.get_reward( function (reward) { - lib.get_supply( function (supply) { - lib.get_estnext( function (estnext) { - lib.get_nextin( function (nextin) { - lib.syncLoop(count, function (loop) { - var i = loop.iteration(); - lib.get_blockhash(height-i, function (hash) { - lib.getBlock(hash, function (block) { - newVotes.push({count:height-i,reward:block.reward,vote:block.vote}); - loop.next(); - }); - }); - }, function(){ - console.log(newVotes); - Heavy.update({coin: coin}, { - lvote: vote, - reward: reward, - supply: supply, - cap: maxmoney, - estnext: estnext, - phase: phase, - maxvote: maxvote, - nextin: nextin, - votes: newVotes, - }, function() { - //console.log('address updated: %s', hash); - return cb(); - }); - }); - }); - }); - }); - }); - }); - }); - }); - }); - }, // updates market data for given market; called by sync.js update_markets_db: function(market, cb) { @@ -599,78 +537,6 @@ module.exports = { }); }, - // updates stats data for given coin; called by sync.js - update_db: function(coin, cb) { - lib.getBlockcount().then(count => { - if (!count) { - console.log('Unable to connect to explorer API'); - return cb(false); - } - return lib.get_supply(supply => - lib.get_connectioncount(connections => - Stats.update({ coin }, { coin, count, supply, connections }, () => cb(true)) - ) - ); - }); - }, - - // updates tx, address & richlist db's; called by sync.js - update_tx_db: function(coin, start, end, timeout, cb) { - var complete = false; - lib.syncLoop((end - start) + 1, function (loop) { - var x = loop.iteration(); - if (x % 5000 === 0) { - Stats.update({coin: coin}, { - last: start + x - 1, - }, function () {}); - } - lib.get_blockhash(start + x, function(blockhash){ - if (blockhash) { - lib.getBlock(blockhash, function(block) { - if (block && block.tx) { - lib.syncLoop(block.tx.length, function (subloop) { - var i = subloop.iteration(); - Tx.findOne({txid: block.tx[i]}, function(err, tx) { - if(tx) { - tx = null; - subloop.next(); - } else { - save_tx(block.tx[i], function(err){ - if (err) { - console.log(err); - } else { - console.log('%s: %s', block.height, block.tx[i]); - } - setTimeout( function(){ - tx = null; - subloop.next(); - }, timeout); - }); - } - }); - }, function(){ - blockhash = null; - block = null; - loop.next(); - }); - } else { - console.log('block not found: %s', blockhash); - loop.next(); - } - }); - } else { - loop.next(); - } - }); - }, function(){ - Stats.update({coin: coin}, { - last: end, - }, function() { - return cb(); - }); - }); - }, - create_peer: function(params, cb) { var newPeer = new Peers(params); newPeer.save(function(err) { @@ -706,8 +572,74 @@ module.exports = { } }); }, + + async getBlocks (searchParams, flds) { + const params = (searchParams.length ? searchParams : [ searchParams ]) + const mode = params.find(param => /[a-z]/i.test(param)) !== undefined ? 'hash' : 'height' + const blockheight = await rpc.getblockcount() + return promisify( + Block[params.length > 1 ? 'find' : 'findOne'].bind(Block), + { [mode]: { $in: params } }, + flds || { } + ).then(([ err, blocks ]) => err || !blocks._doc + ? null + : blocks.length + ? blocks.map(block => dbToRpcBlock(block._doc, blockheight, flds.fulltx === 0 ? null : Object.keys(flds))) + : dbToRpcBlock(blocks._doc, blockheight, params) + ) + }, - setupSchema() { + async updateStats (coin) { + const txoutinfo = await lib.getRawRpc('gettxoutsetinfo') + const mininginfo = await lib.getRawRpc('getmininginfo') + + // Although schema queries return a thenable Query object, they are not full promises and + // thus cannot be used with async/await syntax. + return promisify(Stats.update.bind(Stats), { coin: coin }, { + blocks: mininginfo.blocks, + currentblockweight: mininginfo.currentblockweight, + currentblocktx: mininginfo.currentblocktx, + difficulty: mininginfo.difficulty, + networkhashps: mininginfo.networkhashps, + pooledtx: mininginfo.pooledtx, + chain: mininginfo.chain, + warnings: mininginfo.warnings, + supply: txoutinfo.total_amount, + connections: await lib.getRawRpc('getconnectioncount'), + bestblock: txoutinfo.bestblock, + transactions: txoutinfo.transactions, + txouts: txoutinfo.txouts, + bogosize: txoutinfo.bogosize, + hash_serialized_2: txoutinfo.hash_serialized_2, + disk_size: txoutinfo.disk_size + }) + }, + + async updateDb (start, end, timeout) { + for (let i = start; i < end; i++) { + let [ err, block ] = await promisify(Block.findOne.bind(Block), { height: i }) + if (block) continue + + block = await lib.getRawRpc('getblock', [ await lib.getRawRpc('getblockhash', [ i ]) ]) + if (!block) { + debug(`Block #${i} could not be found, skipping.`) + continue + } else if (!block.tx) { + debug(`Block #${i} does not have any transactions, skipping.`) + continue + } + + debug(`Caching #${i}: ${block.hash}`) + block.fulltx = await Promise.all(block.tx.map(txid => lib.getRawRpc('getrawtransaction', [ txid, 1 ]))) + .then(txs => txs.map((tx, t) => ({ txid: block.tx[t], ...tx })).filter(tx => !tx.code && !tx.name)) + console.log(`${block.height}: ${block.hash}`) + await Block.create([ block ]) + if (timeout) await wait(timeout) + } + + }, + + setupSchema () { return promisify(this.check_stats, settings.coin).then(exists => { // setup stats if (!exists) { @@ -734,18 +666,6 @@ module.exports = { debug(`no richlist entry found, creating...`) return promisify(this.create_richlist, settings.coin) } - }).then(() => { - // check heavy - if (settings.heavy) { - return promisify(this.check_heavy, settings.coin) - } - }).then(exists => { - // create heavy - // must be strong check because exists could be undefined - if (exists === false) { - debug(`no heavy entry found, creating...`) - return promisify(this.create_heavy, settings.coin) - } }) } }; diff --git a/lib/explorer.js b/lib/explorer.js index c588b7a9d..f1186cf28 100644 --- a/lib/explorer.js +++ b/lib/explorer.js @@ -2,34 +2,22 @@ const request = require('request'), debug = require('debug')('explorer:lib'), settings = require('./settings'), Address = require('../models/address'), - Tx = require('../models/tx'), Block = require('../models/block'), - { promisify, requestp, deepEqual } = require('./util') + { promisify, requestp, deepEqual } = require('./util'), + { api } = require('./api') const base_url = 'http://127.0.0.1:' + settings.port + '/api/' -// there are two ways of calculating coinbase supply -// we can use the coinbase address that accumulates a record of all coinbase transactions -// or we can add up all coinbase transactions in the database. -// TODO: Add test to check that both results are equal - -function verifyCoinbaseSupply () { - return promisify(Address.findOne.bind(Address), { a_id: 'coinbase' }).then(([ err, addr ]) => - addr ? addr.balance > 0 ? addr.balance : addr.sent : undefined - ) -} - function coinbase_supply () { - return promisify( - Tx.find.bind(Tx), - { 'vin': { $elemMatch: { 'addresses': 'coinbase', 'amount': { $gt: 0 } } } } - ).then(([ err, txes ]) => - txes.reduce((sum, tx) => sum + tx.vin.find(vin => vin.addresses === 'coinbase').amount, 0) - ) + return requestp(base_url + 'gettxoutsetinfo').then(info => info.total_amount) } module.exports = { + getRawRpc (method, params) { + return api.callRawRpc(method, params) + }, + convert_to_satoshi (amount, cb) { const ret = amount.toFixed(8) * 100000000 return cb ? cb(ret) : ret @@ -111,22 +99,8 @@ module.exports = { }) }, - async getBlock (hash, cb, blockcount) { - blockcount = blockcount || await this.getBlockcount() - const ret = Block.findOne({ hash }).then(block => block - ? { - ...block._doc, - confirmations: blockcount - block.height, - strippedsize: block.size, - versionHex: block.version.toString(16), - nTx: block.tx.length - } - : requestp(`${base_url}getblock?hash=${hash}`).then(body => Promise.all([ - body, - Block.create([ body ]) - ])).then(([ body ]) => body) - ) - + async getBlock (hash, cb) { + const ret = requestp(`${base_url}getblock?hash=${hash}`) return cb ? cb(await ret) : ret }, @@ -137,55 +111,6 @@ module.exports = { }) }, - get_maxmoney: function (cb) { - var uri = base_url + 'getmaxmoney' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_maxvote: function (cb) { - var uri = base_url + 'getmaxvote' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_vote: function (cb) { - var uri = base_url + 'getvote' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_phase: function (cb) { - var uri = base_url + 'getphase' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_reward: function (cb) { - var uri = base_url + 'getreward' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_estnext: function (cb) { - var uri = base_url + 'getnextrewardestimate' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - - get_nextin: function (cb) { - var uri = base_url + 'getnextrewardwhenstr' - request({uri: uri, json: true}, function (error, response, body) { - return cb(body) - }) - }, - // synchonous loop used to interate through an array, // avoid use unless absolutely neccessary syncLoop: function (iterations, process, exit) { @@ -255,7 +180,7 @@ module.exports = { return cb(body.total_amount) }) } else { - return coinbase_supply().then(supply => cb(supply / 100000000)) + return coinbase_supply() } }, @@ -306,7 +231,7 @@ module.exports = { else acc[index].amount += vin.amount return acc }, [])).then(vins => { - if (tx.vin.filter(vin => vin.coinbase).length) { + if (tx.vin.find(vin => vin.coinbase)) { vins.push({ addresses: 'coinbase', amount: tx.vout.reduce((acc, vout) => acc + vout.value * 1e8, 0) - vins.reduce((acc, vin) => acc + vin.amout, 0) diff --git a/lib/locale.js b/lib/locale.js index 6f98aaf4f..e00a43ccf 100644 --- a/lib/locale.js +++ b/lib/locale.js @@ -123,21 +123,6 @@ exports.mkt_total = "Total", exports.mkt_trade_history = "Trade History", exports.mkt_type = "Type", exports.mkt_time_stamp = "Time Stamp", -// Heavy - -exports.heavy_vote = "Vote", - // Heavy rewards view -exports.heavy_title = "Reward/voting information", - -exports.heavy_cap = "Coin Cap", -exports.heavy_phase = "Phase", -exports.heavy_maxvote = "Max Vote", -exports.heavy_reward = "Reward", -exports.heavy_current = "Current Reward", -exports.heavy_estnext = "Est. Next", -exports.heavy_changein = "Reward change in approximately", -exports.heavy_key = "Key", -exports.heavy_lastxvotes = "Last 20 votes", exports.poloniex = "Poloniex", exports.bittrex = "Bittrex", diff --git a/lib/settings.js b/lib/settings.js index fbe0c7e98..da4a90233 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -50,16 +50,15 @@ exports.dbsettings = safeGet('dbsettings') || { //This setting is passed to the wallet -// must be of this format in order for bitcoin-node-api to accept it -const cleanupValue = value => value.replace(/[^\w\.\:\/\=]/g, '') +// must be of this format in order for bitcoin-core to accept it const savedWallet = safeGet('wallet') || { url: '' }; -const [host, port] = cleanupValue(savedWallet.url).split('://').slice(-1)[0].split(':') || [] +const [ host, port ] = savedWallet.url.split('://').slice(-1)[0].split(':') || [] console.log(`- settings: host=${host}, port=${port}`) +delete savedWallet['url'] exports.wallet = { + ...savedWallet, 'host' : host || '127.0.0.1', 'port' : port || 8669, - 'user' : cleanupValue(savedWallet.username) || 'bitcoinrpc', - 'pass' : cleanupValue(savedWallet.password) || 'password' }; @@ -132,12 +131,11 @@ exports.check_timeout = safeGet('check_timeout') || 250; exports.sync_timeout = safeGet('sync_timeout') || 60000; exports.market_timeout = safeGet('market_timeout') || 120000; exports.peer_timeout = safeGet('peer_timeout') || 240000; - +exports.ui_interval = safeGet('ui_interval') || 30000; //genesis exports.genesis_tx = safeGet('genesis_tx') || '65f705d2f385dc85763a317b3ec000063003d6b039546af5d8195a5ec27ae410'; exports.genesis_block = safeGet('genesis_block') || 'b2926a56ca64e0cd2430347e383f63ad7092f406088b9b86d6d68c2a34baef51'; -exports.heavy = safeGet('heavy') || false; exports.txcount = safeGet('txcount') || 100; exports.show_sent_received = safeGet('show_sent_received') || true; exports.supply = safeGet('supply') || 'COINBASE'; diff --git a/lib/util.js b/lib/util.js index 2a674fae8..b7b900511 100644 --- a/lib/util.js +++ b/lib/util.js @@ -2,7 +2,7 @@ const request = require('request') const spawn = require('child_process').spawn module.exports = { - deepEqual(a, b) { + deepEqual (a, b) { if (!(a instanceof Object) || !(b instanceof Object)) return a === b if (Object.keys(a).filter(k => !b.hasOwnProperty(k)).length || Object.keys(b).filter(k => !a.hasOwnProperty(k)).length) return false return !Object.keys(a).concat(Object.keys(b)).map(k => module.exports.deepEqual(a[k], b[k])).includes(false) @@ -20,7 +20,7 @@ module.exports = { * @param {...any} args arguments for the function * @returns {Promise} promise that resolves with returned values when async task is complete (i.e. the callback is called) */ - promisify(func, ...args) { + promisify (func, ...args) { return new Promise((resolve, reject) => { func(...args, (...cbArgs) => resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0])) }) @@ -33,20 +33,20 @@ module.exports = { * @param {...any} args remaining arguments passed to the function * @returns {Promise} promise that resolves with returned values when async task is complete */ - promisifyPos(func, cbPos, ...args) { + promisifyPos (func, cbPos, ...args) { return new Promise((resolve, reject) => { func(...args.slice(0, cbPos), (...cbArgs) => resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]), ...args.slice(cbPos)) }) }, - requestp(uri, { json = true, simple = true } = {}) { + requestp (uri, { json = true, simple = true } = {}) { const promise = module.exports.promisify(request, uri, { json }) return simple ? promise.then(([error, response, body]) => error ? Promise.reject(error) : body) : promise }, - spawnCmd(cmd, options, hooks = {}) { + spawnCmd (cmd, options, hooks = {}) { return new Promise((resolve, reject) => { const child = spawn(cmd, options) child.stdout.setEncoding('utf-8') @@ -69,7 +69,17 @@ module.exports = { }) }, - prettyPrint(obj) { + prettyPrint (obj) { return JSON.stringify(obj, null, 2) + }, + + renameProp (oldProp, newProp, { [oldProp]: old, ...others }) { + return { [newProp]: old, ...others } + }, + + wait (millis) { + return new Promise((resolve, reject) => { + setTimeout(() => resolve(), millis) + }) } } \ No newline at end of file diff --git a/locale/en.json b/locale/en.json index ca5d3b442..b2c05c7fd 100644 --- a/locale/en.json +++ b/locale/en.json @@ -137,18 +137,5 @@ "empoex": "Empoex", "cryptsy": "Cryptsy", "cryptopia": "Cryptopia", - "ccex": "C-Cex", - - // Heavy rewards view - "heavy_title": "Reward/voting information", - "heavy_vote": "Vote", - "heavy_cap": "Coin Cap", - "heavy_phase": "Phase", - "heavy_maxvote": "Max Vote", - "heavy_reward": "Reward", - "heavy_current": "Current Reward", - "heavy_estnext": "Est. Next", - "heavy_changein": "Reward change in approximately", - "heavy_key": "Key", - "heavy_lastxvotes": "Last 20 votes" + "ccex": "C-Cex" } diff --git a/log.txt b/log.txt new file mode 100644 index 000000000..e9e95e91c --- /dev/null +++ b/log.txt @@ -0,0 +1,820 @@ + +> explorer@1.6.2-equibit start /home/eternali/equibit/explorer +> node --stack-size=10000 ./bin/cluster + +- settings: host=169.53.165.114, port=18331 + + +Run again + + +Fri, 21 Dec 2018 16:26:59 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:26:59 GMT express:router:layer new +Fri, 21 Dec 2018 16:26:59 GMT express:router use / query +Fri, 21 Dec 2018 16:26:59 GMT express:router:layer new +Fri, 21 Dec 2018 16:26:59 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:26:59 GMT express:router:route new * +Fri, 21 Dec 2018 16:26:59 GMT express:router:layer new * +Fri, 21 Dec 2018 16:26:59 GMT express:router:route get * +Fri, 21 Dec 2018 16:26:59 GMT express:router:route get * +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 +- settings: host=169.53.165.114, port=18331 + + + +Run again + + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode + +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new + +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query + +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new + +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit + +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * + +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * + +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * + +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * + + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +ERROR: Fri, 21 Dec 2018 16:27:00 GMT explorer:sync args:: [ 'index', 'update' ] + + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +ERROR: Fri, 21 Dec 2018 16:27:00 GMT explorer:sync - database=index, mode=update + +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +ERROR: Fri, 21 Dec 2018 16:27:00 GMT explorer:sync Script already running. + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Process exited with code 0 + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous + + +Run again + + +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get * +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get / +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /info +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /markets/:market +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /richlist +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /movement +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /network +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /tx/:txid +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /block/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /address/:hash/:count +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route post /search +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /qr/:string +Fri, 21 Dec 2018 16:27:00 GMT express:router:route new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:router:route get /ext/summary +Fri, 21 Dec 2018 16:27:00 GMT express:application booting in development mode +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / query +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / expressInit +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /version +Fri, 21 Dec 2018 16:27:00 GMT express:router use /version anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / favicon +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / logger +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / jsonParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / urlencodedParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / cookieParser +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / staticMiddleware +Fri, 21 Dec 2018 16:27:00 GMT express:application .use app under /api +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /api +Fri, 21 Dec 2018 16:27:00 GMT express:router use /api fn +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / router +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getmoneysupply +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getmoneysupply anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getaddress/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getaddress/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getbalance/:hash +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getbalance/:hash anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getdistribution +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getdistribution anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/getblocks/:start/:end +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/getblocks/:start/:end anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new /ext/connections +Fri, 21 Dec 2018 16:27:00 GMT express:router use /ext/connections anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous +Fri, 21 Dec 2018 16:27:00 GMT express:router:layer new +Fri, 21 Dec 2018 16:27:00 GMT express:router use / anonymous diff --git a/models/address.js b/models/address.js index 348fc8b5b..779b7883a 100644 --- a/models/address.js +++ b/models/address.js @@ -2,12 +2,12 @@ var mongoose = require('mongoose') , Schema = mongoose.Schema; var AddressSchema = new Schema({ - a_id: { type: String, unique: true, index: true}, + a_id: { type: String, unique: true, index: false }, txs: { type: Array, default: [] }, received: { type: Number, default: 0 }, sent: { type: Number, default: 0 }, - balance: {type: Number, default: 0}, -}, {id: false}); + balance: {type: Number, default: 0 }, +}, { id: false }); module.exports = mongoose.model('Address', AddressSchema); diff --git a/models/block.js b/models/block.js index fccc010ce..ca2307c66 100644 --- a/models/block.js +++ b/models/block.js @@ -1,13 +1,28 @@ const mongoose = require('mongoose') +const TxSchema = new mongoose.Schema({ + txid: { type: String, lowercase: true, unique: true }, + version: { type: Number }, + size: { type: Number }, + vsize: { type: Number }, + locktime: { type: Number, default: 0 }, + vin: { type: Array, default: [] }, + vout: { type: Array, default: [] }, + EQB_type: { type: Number }, + EQB_payload: { type: String }, + hex: { type: String, lowercase: true, unique: true }, + time: { type: Number }, +}) + const BlockSchema = new mongoose.Schema({ - hash: { type: String, lowercase: true, unique: true, index: true }, + hash: { type: String, lowercase: true, unique: true }, size: { type: Number }, weight: { type: Number }, height: { type: Number }, version: { type: Number }, merkleroot: { type: String, lowercase: true }, - tx: { type: Array, default: [] }, + tx: { type: Array }, + fulltx: [ TxSchema ], time: { type: Number }, mediantime: { type: Number }, bits: { type: String, lowercase: true }, @@ -16,6 +31,6 @@ const BlockSchema = new mongoose.Schema({ chainwork: { type: String, lowercase: true }, previousblockhash: { type: String, lowercase: true }, nextblockhash: { type: String, lowercase: true }, -}, { id: false }) +}) module.exports = mongoose.model('Block', BlockSchema) diff --git a/models/heavy.js b/models/heavy.js deleted file mode 100644 index 02a461a4d..000000000 --- a/models/heavy.js +++ /dev/null @@ -1,21 +0,0 @@ -var mongoose = require('mongoose') - , Schema = mongoose.Schema; - -var HeavySchema = new Schema({ - coin: { type: String }, - lvote: { type: Number, default: 0 }, - reward: { type: Number, default: 0 }, - supply: { type: Number, default: 0 }, - cap: { type: Number, default: 0 }, - estnext: { type: Number, default: 0 }, - phase: { type: String, default: 'N/A'}, - maxvote: { type: Number, default: 0 }, - nextin: { type: String, default: 'N/A'}, - votes: { type: Array, default: [] }, -}); - -module.exports = mongoose.model('Heavy', HeavySchema); - -/* -votes : [{ count: 0, reward: 0, vote: 0}] -*/ diff --git a/models/stats.js b/models/stats.js index 6d2f21788..ff0363d8e 100644 --- a/models/stats.js +++ b/models/stats.js @@ -3,13 +3,23 @@ var mongoose = require('mongoose') var StatsSchema = new Schema({ coin: { type: String }, - count: { type: Number, default: 1 }, - last: { type: Number, default: 1 }, - //difficulty: { type: Object, default: {} }, - //hashrate: { type: String, default: 'N/A' }, + blocks: { type: Number, default: 1 }, + currentblockweight: { type: Number, default: 4000 }, + currentblocktx: { type: Number, default: 0 }, + difficulty: { type: String, default: 1 }, + networkhashps: { type: String, default: 'N/A' }, + pooledtx: { type: Number, default: 0 }, + chain: { type: String }, + warnings: { type: String, default: "" }, supply: { type: Number, default: 0 }, connections: { type: Number, default: 0 }, - last_price: { type: Number, default: 0 }, + bestblock: { type: String, lowercase: true }, + transactions: { type: Number, default: 0 }, + txouts: { type: Number, default: 0 }, + bogosize: { type: Number, default: 0 }, + hash_serialized_2: { type: String, lowercase: true }, + disk_size: { type: Number, default: 0 }, + last_price: { type: Number, default: 0 } }); -module.exports = mongoose.model('coinstats', StatsSchema); \ No newline at end of file +module.exports = mongoose.model('stats', StatsSchema); \ No newline at end of file diff --git a/models/tx.js b/models/tx.js deleted file mode 100644 index 3d2a0a39e..000000000 --- a/models/tx.js +++ /dev/null @@ -1,14 +0,0 @@ -var mongoose = require('mongoose') - , Schema = mongoose.Schema; - -var TxSchema = new Schema({ - txid: { type: String, lowercase: true, unique: true, index: true}, - vin: { type: Array, default: [] }, - vout: { type: Array, default: [] }, - total: { type: Number, default: 0 }, - timestamp: { type: Number, default: 0 }, - blockhash: { type: String }, - blockindex: {type: Number, default: 0}, -}, {id: false}); - -module.exports = mongoose.model('Tx', TxSchema); diff --git a/package-lock.json b/package-lock.json index 1bbbc3c9d..b700b1fbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,14 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@uphold/request-logger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@uphold/request-logger/-/request-logger-2.0.0.tgz", + "integrity": "sha1-xYXAvblCEBmJRcZZfk/iPW5j4IQ=", + "requires": { + "uuid": "^3.0.1" + } + }, "accepts": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", @@ -46,6 +54,14 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, "aws-sign2": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", @@ -56,6 +72,11 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -64,41 +85,24 @@ "tweetnacl": "^0.14.3" } }, - "bitcoin": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/bitcoin/-/bitcoin-1.7.0.tgz", - "integrity": "sha1-OeVzZG9NiBeYmODOhuNcs538afE=", - "requires": { - "deprecate": "~0.1.0" - } + "bignumber.js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", + "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" }, - "bitcoin-node-api": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bitcoin-node-api/-/bitcoin-node-api-0.1.0.tgz", - "integrity": "sha1-3r88cxzRAnckoI3ovTKMY2Tr6O4=", + "bitcoin-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bitcoin-core/-/bitcoin-core-2.0.0.tgz", + "integrity": "sha512-I6I7ejzbXfyMtR5/z0BhfjTeN8PMQGD+1B1rpu6IoLcwqoybaSa+P4zYnja/p2xdqjdctmgbOtAaCaaqyVCycQ==", "requires": { - "bitcoin": "1.7.0", - "express": "3.3.x" - }, - "dependencies": { - "express": { - "version": "3.3.8", - "resolved": "http://registry.npmjs.org/express/-/express-3.3.8.tgz", - "integrity": "sha1-jpisMNgfTJW4XXHSr2z4T2LvGb0=", - "requires": { - "buffer-crc32": "0.2.1", - "commander": "1.2.0", - "connect": "2.8.8", - "cookie": "0.1.0", - "cookie-signature": "1.0.1", - "debug": "*", - "fresh": "0.2.0", - "methods": "0.0.1", - "mkdirp": "0.3.5", - "range-parser": "0.0.4", - "send": "0.1.4" - } - } + "@uphold/request-logger": "^2.0.0", + "bluebird": "^3.4.1", + "debugnyan": "^1.0.0", + "json-bigint": "^0.2.0", + "lodash": "^4.0.0", + "request": "^2.53.0", + "semver": "^5.1.0", + "standard-error": "^1.1.0" } }, "bl": { @@ -107,28 +111,13 @@ "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", "requires": { "readable-stream": "~2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - } } }, + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" + }, "body-parser": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", @@ -141,7 +130,7 @@ "dependencies": { "qs": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", + "resolved": "http://registry.npmjs.org/qs/-/qs-0.6.6.tgz", "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" } } @@ -154,15 +143,40 @@ "hoek": "2.x.x" } }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "bson": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", + "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" + }, "buffer-crc32": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=" }, + "bunyan": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", + "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.10.6", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, "bytes": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-0.2.0.tgz", - "integrity": "sha1-qtM+wU49wsp06OfUUfm6BTrU96A=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" }, "camelcase": { "version": "1.2.1", @@ -200,40 +214,23 @@ } }, "commander": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-1.2.0.tgz", - "integrity": "sha1-/VcTv6FTx9bMWZN4patMRcU1Ap4=", - "requires": { - "keypress": "0.1.x" - } + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/config/-/config-3.0.0.tgz", - "integrity": "sha512-QMr3BCOcHdgXx8t8cLfBhWtHcIAAMikaxUc2XASuH2A93g9kOIRch7sXFQdSvdMxhQobnctWm2y68YJYRttJlw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/config/-/config-3.0.1.tgz", + "integrity": "sha512-TBNrrk2b6AybUohqXw2AydglFBL9b/+1GG93Di6Fm6x1SyVJ5PYgo+mqY2X0KpU9m0PJDSbFaC5H95utSphtLw==", "requires": { "json5": "^1.0.1" } }, - "connect": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/connect/-/connect-2.8.8.tgz", - "integrity": "sha1-uav4yvC9l3PLPeopNEEZhyWCRG0=", - "requires": { - "buffer-crc32": "0.2.1", - "bytes": "0.2.0", - "cookie": "0.1.0", - "cookie-signature": "1.0.1", - "debug": "*", - "formidable": "1.0.14", - "fresh": "0.2.0", - "methods": "0.0.1", - "pause": "0.0.1", - "qs": "0.6.5", - "send": "0.1.4", - "uid2": "0.0.2" - } - }, "constantinople": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-2.0.1.tgz", @@ -254,19 +251,12 @@ "requires": { "cookie": "0.1.0", "cookie-signature": "1.0.3" - }, - "dependencies": { - "cookie-signature": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", - "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" - } } }, "cookie-signature": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz", - "integrity": "sha1-ROByFIrwHm6OJK+/EmkNaK5pjss=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", + "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" }, "core-util-is": { "version": "1.0.2", @@ -320,6 +310,25 @@ "resolved": "http://registry.npmjs.org/debug/-/debug-0.7.4.tgz", "integrity": "sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk=" }, + "debugnyan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/debugnyan/-/debugnyan-1.0.0.tgz", + "integrity": "sha1-kDhtXrwsY1iPF/Jyvlwqk7dmXYM=", + "requires": { + "bunyan": "^1.8.1", + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", @@ -330,10 +339,14 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, - "deprecate": { - "version": "0.1.0", - "resolved": "http://registry.npmjs.org/deprecate/-/deprecate-0.1.0.tgz", - "integrity": "sha1-xJBYYS3GyOUUXq/kg5uMLH0EHBQ=" + "dtrace-provider": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", + "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=", + "optional": true, + "requires": { + "nan": "^2.10.0" + } }, "ecc-jsbn": { "version": "0.1.2", @@ -383,54 +396,15 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" }, - "cookie-signature": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", - "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" - }, "debug": { "version": "0.8.1", "resolved": "http://registry.npmjs.org/debug/-/debug-0.8.1.tgz", "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" }, - "fresh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" - }, - "methods": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.0.0.tgz", - "integrity": "sha1-mnPYY3XfzvJu9hyj5Lii4lOKgOM=" - }, "qs": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", + "resolved": "http://registry.npmjs.org/qs/-/qs-0.6.6.tgz", "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" - }, - "range-parser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" - }, - "send": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", - "requires": { - "buffer-crc32": "0.2.1", - "debug": "0.8.0", - "fresh": "~0.2.1", - "mime": "1.2.11", - "range-parser": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "0.8.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-0.8.0.tgz", - "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" - } - } } } }, @@ -457,27 +431,12 @@ "async": "^2.0.1", "combined-stream": "^1.0.5", "mime-types": "^2.1.11" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" - } - } } }, - "formidable": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.14.tgz", - "integrity": "sha1-Kz9MQRy7X91pXESEPiojUUpDIxo=" - }, "fresh": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz", - "integrity": "sha1-v9lALPPfEsSkwxDHn5mj3eE9NKc=" + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", + "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" }, "generate-function": { "version": "2.3.1", @@ -511,13 +470,16 @@ } }, "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "dev": true, + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, "requires": { + "inflight": "^1.0.4", "inherits": "2", - "minimatch": "0.3" + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "har-validator": { @@ -529,13 +491,6 @@ "commander": "^2.9.0", "is-my-json-valid": "^2.12.4", "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" - } } }, "has-ansi": { @@ -572,6 +527,16 @@ "sshpk": "^1.7.0" } }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -609,6 +574,11 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -632,6 +602,11 @@ "version": "2.1.0", "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz", "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=" + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=" } } }, @@ -643,6 +618,28 @@ "requires": { "glob": "^3.2.11", "jasmine-core": "~2.1.0" + }, + "dependencies": { + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2", + "minimatch": "0.3" + } + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } } }, "jasmine-core": { @@ -656,6 +653,14 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "json-bigint": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.2.3.tgz", + "integrity": "sha1-EY1/b/HThlnxn5TPc+ZKdaP5iKg=", + "requires": { + "bignumber.js": "^4.0.0" + } + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -672,6 +677,13 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "requires": { "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } } }, "jsonminify": { @@ -702,10 +714,10 @@ } } }, - "keypress": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz", - "integrity": "sha1-SjGI1CkbZrT2XtuZ+AaqmuKTWSo=" + "kareem": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", + "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" }, "lodash": { "version": "4.17.11", @@ -720,7 +732,8 @@ "lru-cache": { "version": "2.7.3", "resolved": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true }, "markdown-js": { "version": "0.0.3", @@ -731,9 +744,9 @@ } }, "memory-pager": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.1.0.tgz", - "integrity": "sha512-Mf9OHV/Y7h6YWDxTzX/b4ZZ4oh9NSXblQL8dtPCOomOtZciEHxePR78+uHFLLlsk01A6jVHhHsQZZ/WcIPpnzg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.3.1.tgz", + "integrity": "sha512-pUf/sGkym2WqFZYTVmdASnSbNfpGc9rwxEHOePx4lT/fD+NHGL1U16Uy4o6PMiVcDv4mp6MI/vaF0c/Kd1QEUQ==", "optional": true }, "merge-descriptors": { @@ -742,13 +755,13 @@ "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" }, "methods": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/methods/-/methods-0.0.1.tgz", - "integrity": "sha1-J3yQ+L7zlwlkWoNxxRw7bGSOBow=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.0.0.tgz", + "integrity": "sha1-mnPYY3XfzvJu9hyj5Lii4lOKgOM=" }, "mime": { "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "resolved": "http://registry.npmjs.org/mime/-/mime-1.2.11.tgz", "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" }, "mime-db": { @@ -765,23 +778,33 @@ } }, "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "lru-cache": "2", - "sigmund": "~1.0.0" + "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true }, "mkdirp": { - "version": "0.3.5", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=" + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "moment": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz", + "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==", + "optional": true }, "mongodb": { "version": "3.1.10", @@ -790,30 +813,23 @@ "requires": { "mongodb-core": "3.1.9", "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bson": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", - "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" - }, - "mongodb-core": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.9.tgz", - "integrity": "sha512-MJpciDABXMchrZphh3vMcqu8hkNf/Mi+Gk6btOimVg1XMxLXh87j6FAvRm+KmwD1A9fpu3qRQYcbQe4egj23og==", - "requires": { - "bson": "^1.1.0", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - } - } + } + }, + "mongodb-core": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.9.tgz", + "integrity": "sha512-MJpciDABXMchrZphh3vMcqu8hkNf/Mi+Gk6btOimVg1XMxLXh87j6FAvRm+KmwD1A9fpu3qRQYcbQe4egj23og==", + "requires": { + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" } }, "mongoose": { - "version": "5.3.14", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.3.14.tgz", - "integrity": "sha512-Vt7uC0+/SuPb+x6IwbtXl4tkUER1xU9INlfrDK1RdfsvvEMfG3FJUGNPVGeTWQaj8xqMBtZKIdUNt58rIAsCYg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.4.0.tgz", + "integrity": "sha512-pFKa6askJ6xwZT6mWuYBwa2R9ryd1+JrXUhKuAUxEGrUMTi8ADcJC/RgBg4fZ1lL6VPVVChsc9wpVn4X6gcWlg==", "requires": { "async": "2.6.1", "bson": "~1.1.0", @@ -828,72 +844,6 @@ "regexp-clone": "0.0.1", "safe-buffer": "5.1.2", "sliced": "1.0.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" - } - }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" - }, - "bson": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", - "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "kareem": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", - "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" - }, - "mongodb-core": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.9.tgz", - "integrity": "sha512-MJpciDABXMchrZphh3vMcqu8hkNf/Mi+Gk6btOimVg1XMxLXh87j6FAvRm+KmwD1A9fpu3qRQYcbQe4egj23og==", - "requires": { - "bson": "^1.1.0", - "require_optional": "^1.0.1", - "safe-buffer": "^5.1.2", - "saslprep": "^1.0.0" - } - }, - "mpath": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", - "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" - }, - "mquery": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", - "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", - "requires": { - "bluebird": "3.5.1", - "debug": "3.1.0", - "regexp-clone": "0.0.1", - "safe-buffer": "5.1.2", - "sliced": "1.0.1" - } - }, - "sliced": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", - "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" - } } }, "mongoose-legacy-pluralize": { @@ -924,26 +874,84 @@ } } }, + "mpath": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.5.1.tgz", + "integrity": "sha512-H8OVQ+QEz82sch4wbODFOz+3YQ61FYz/z3eJ5pIdbMEaUzDqA268Wd+Vt4Paw9TJfvDgVKaayC0gBzMIw2jhsg==" + }, + "mquery": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", + "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + } + }, + "nan": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.0.tgz", + "integrity": "sha512-zT5nC0JhbljmyEf+Z456nvm7iO7XgRV2hYxoBtPpnyp+0Q4aCoP6uWNn76v/I6k2kCYNLWqWbwBWQcjsNI/bjw==", + "optional": true + }, + "ncp": { + "version": "2.0.0", + "resolved": "http://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, "negotiator": { "version": "0.4.9", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" - }, "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, "optimist": { "version": "0.3.7", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", @@ -957,16 +965,17 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "optional": true + }, "path-to-regexp": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" }, - "pause": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", - "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" - }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", @@ -1004,14 +1013,14 @@ "integrity": "sha1-984WQaxdwZUExBqGnfHEuCfXjg0=" }, "qs": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.5.tgz", - "integrity": "sha1-KUsmjksNQlD23eGbO4s0k13/FO8=" + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=" }, "range-parser": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz", - "integrity": "sha1-wEJ//vUcEKy6B4KkbJYC50T/Ygs=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", + "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" }, "raw-body": { "version": "1.1.7", @@ -1020,13 +1029,19 @@ "requires": { "bytes": "1", "string_decoder": "0.10" - }, - "dependencies": { - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" - } + } + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" } }, "readdirp": { @@ -1070,10 +1085,10 @@ "tunnel-agent": "~0.4.1" }, "dependencies": { - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=" + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" } } }, @@ -1091,11 +1106,26 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, + "rimraf": { + "version": "2.4.5", + "resolved": "http://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1116,14 +1146,22 @@ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, "send": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/send/-/send-0.1.4.tgz", - "integrity": "sha1-vnDY0b4B3mGCGvE3gLUDRaT3Gr0=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", + "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", "requires": { - "debug": "*", - "fresh": "0.2.0", - "mime": "~1.2.9", - "range-parser": "0.0.4" + "buffer-crc32": "0.2.1", + "debug": "0.8.0", + "fresh": "~0.2.1", + "mime": "1.2.11", + "range-parser": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "0.8.0", + "resolved": "http://registry.npmjs.org/debug/-/debug-0.8.0.tgz", + "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" + } } }, "serve-static": { @@ -1133,41 +1171,18 @@ "requires": { "parseurl": "1.0.1", "send": "0.3.0" - }, - "dependencies": { - "debug": { - "version": "0.8.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-0.8.0.tgz", - "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" - }, - "fresh": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.4.tgz", - "integrity": "sha1-NYJJkgbJcjcUGQ7ddLRgT+tKYUw=" - }, - "range-parser": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.3.tgz", - "integrity": "sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU=" - }, - "send": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", - "requires": { - "buffer-crc32": "0.2.1", - "debug": "0.8.0", - "fresh": "~0.2.1", - "mime": "1.2.11", - "range-parser": "~1.0.0" - } - } } }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, "sntp": { "version": "1.0.9", @@ -1217,6 +1232,11 @@ } } }, + "standard-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz", + "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ=" + }, "static-favicon": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/static-favicon/-/static-favicon-1.0.2.tgz", @@ -1224,7 +1244,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "stringstream": { @@ -1255,7 +1275,7 @@ }, "tough-cookie": { "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "resolved": "http://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "requires": { "punycode": "^1.4.1" @@ -1323,11 +1343,6 @@ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=" }, - "uid2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.2.tgz", - "integrity": "sha1-EH+xVcgsETZiB5ftTIjPKwj2qrg=" - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1338,6 +1353,11 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -1373,6 +1393,11 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index cf7937ab6..8124dd152 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "debug": "node --inspect --stack-size=10000 ./bin/cluster" }, "dependencies": { - "bitcoin-node-api": "0.1.0", + "bitcoin-core": "^2.0.0", "body-parser": "~1.0.0", "config": "^3.0.0", "cookie-parser": "~1.0.1", diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index d58cb4b5d..eff52f852 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -159,3 +159,8 @@ tr { bottom: 0px; } +/* Override DataTables ugly gradient processing overlay */ +div#blocks-table_processing.dataTables_processing { + background-color: transparent; + background: transparent; +} diff --git a/routes/index.js b/routes/index.js index dd19000aa..9155424ac 100644 --- a/routes/index.js +++ b/routes/index.js @@ -13,19 +13,11 @@ function route_get_block(res, blockhash) { if (blockhash === settings.genesis_block) { res.render('block', { active: 'block', block: block, confirmations: settings.confirmations, txs: 'GENESIS'}); } else { - db.getTxs(block).then(txs => { + db.getTxs({ hash: blockhash }).then(txs => { if (txs && txs.length > 0) { res.render('block', { active: 'block', block: block, confirmations: settings.confirmations, txs: safeRender(txs) }); } else { - db.create_txs(block, function () { - db.getTxs(block).then(ntxs => { - if (ntxs && ntxs.length > 0) { - res.render('block', { active: 'block', block: block, confirmations: settings.confirmations, txs: safeRender(ntxs) }); - } else { - route_get_index(res, 'Block not found: ' + blockhash); - } - }); - }); + route_get_index(res, 'Block not found: ' + blockhash); } }); } @@ -90,7 +82,7 @@ function route_get_tx(res, txid) { } function route_get_index(res, error) { - res.render('index', { active: 'home', error: error, warning: null }); + res.render('index', { active: 'home', error: error, warning: null, ui_interval: settings.ui_interval }); } function route_get_address(res, hash, count) { @@ -195,27 +187,6 @@ router.get('/network', function(req, res) { res.render('network', {active: 'network'}); }); -router.get('/reward', function(req, res){ - //db.get_stats(settings.coin, function (stats) { - console.log(stats); - db.get_heavy(settings.coin, function (heavy) { - //heavy = heavy; - var votes = heavy.votes; - votes.sort(function (a,b) { - if (a.count < b.count) { - return -1; - } else if (a.count > b.count) { - return 1; - } else { - return 0; - } - }); - - res.render('reward', { active: 'reward', stats: stats, heavy: heavy, votes: heavy.votes }); - }); - //}); -}); - router.get('/tx/:txid', function(req, res) { route_get_tx(res, req.param('txid')); }); diff --git a/scripts/sync.js b/scripts/sync.js index 0576be88a..75f952ed9 100644 --- a/scripts/sync.js +++ b/scripts/sync.js @@ -1,11 +1,10 @@ const mongoose = require('mongoose'), db = require('../lib/database'), - Tx = require('../models/tx'), + Block = require('../models/block'), Address = require('../models/address'), Richlist = require('../models/richlist'), - Stats = require('../models/stats'), settings = require('../lib/settings'), - { promisify, prettyPrint } = require('../lib/util'), + { promisify } = require('../lib/util'), fs = require('fs'), debug = require('debug')('explorer:sync') @@ -113,107 +112,74 @@ function exit(database) { //////// MAIN ENTRYPOINT //////// const { database, mode } = parseArgs(process.argv.slice(2)) -function main() { +async function main() { debug(`- database=${database}, mode=${mode}`) - isLocked(database).then(exists => { - // if there's a lock file, exit - if (exists) { - debug('Script already running.') - process.exit() + + // watch for concurrent execution with lockfiles + if (await isLocked(database)) { + debug('Script already running.') + process.exit() + } + await createLock(database).catch(e => { + debug('Error: unable to create lock file.') + process.exit(1) + }) + + debug('Script launched with pid: ' + process.pid) + await db.connect(settings.dbsettings).catch(err => { + return exit(database) + }) + + if (database === 'index') { + if (!(await promisify(db.check_stats, settings.coin))) { + debug(`Run 'npm start' to create database structure before running this script.`) + exit(database) } - }).then(() => - createLock(database).catch(e => { - debug('Error: unable to create lock file.') - process.exit(1) - }) - ).then(() => { - debug('Script launched with pid: ' + process.pid) - return mongoose.connect(settings.dbsettings.uri, settings.dbsettings.options) - }).then(() => { - if (database === 'index') { - return promisify(db.get_stats, settings.coin).then(() => - promisify(db.check_stats, settings.coin) - ).then(exists => { - if (!exists) { - debug('Run \'npm start\' to create database structure before running this script.') - exit(database) - } - return promisify(db.get_stats, settings.coin) - }).then(stats => { - if (mode === 'reindex') { - return promisify(Tx.remove.bind(Tx), {}).then(err => - promisify(Address.remove.bind(Address), {}) - ).then(err => - promisify(Richlist.update.bind(Richlist), { coin: settings.coin }, { received: [], balance: [] }) - ).then(err => - promisify(Stats.update.bind(Stats), { coin: settings.coin }, { last: 0 }) - ).then(() => { - debug(`\n\n${stats.count}\n\n`) - debug('index cleared (reindex)') - return promisify(db.update_tx_db, settings.coin, 1, stats.count, settings.update_timeout) - }).then(() => - promisify(db.update_richlist, 'received') - ).then(() => - promisify(db.update_richlist, 'balance') - ).then(() => - promisify(db.get_stats, settings.coin) - ).then(nstats => { - debug(`reindex complete (block: ${nstats.last})`) - }) - } else if (mode === 'check') { - return promisify(db.update_tx_db, settings.coin, 1, stats.count, settings.check_timeout).then(() => - promisify(db.get_stats, settings.coin) - ).then(nstats => { - debug(`check complete (block: ${nstats.last})`) - }) - } else if (mode === 'update') { - return promisify(db.update_tx_db, settings.coin, stats.last, stats.count, settings.update_timeout).then(() => - promisify(db.update_richlist, 'received') - ).then(() => - promisify(db.update_richlist, 'balance') - ).then(() => - promisify(db.get_stats, settings.coin) - ).then(nstats => { - debug(`update complete (block: ${nstats.last})`) + + await db.updateStats(settings.coin) + const stats = await promisify(db.get_stats, settings.coin) + + if (mode === 'reindex') { + await promisify(Block.remove.bind(Block), {}) + await promisify(Address.remove.bind(Address), {}) + await promisify(Richlist.update.bind(Richlist), { coin: settings.coin }, { received: [], balance: [] }) + + debug('[reindex]: index cleared') + } + + await db.updateDb(0, stats.blocks, settings.update_timeout) + + if (mode === 'check') { + debug(`[check]: complete`) + return + } + + await promisify(db.update_richlist, 'received') + await promisify(db.update_richlist, 'balance') + + debug(`[${mode}]: index complete (${stats.blocks})`) + exit(database) + } else { + await settings.markets.enabled.reduce((complete, m, _, markets) => { + return promisify(db.check_market, m).then(([m, exists]) => { + complete++ + if (exists) { + return promisify(db.update_markets_db, m).then(err => { + if (err) debug(`${m}: ${err}`) + else debug(`${m} market data updated successfully.`) + if (complete === markets.length) exit() + return complete }) } - }).then(() => - promisify(db.update_db, settings.coin) - ).then(() => - promisify(db.get_stats, settings.coin) - ).then(stats => { - if (settings.heavy) return promisify(db.update_heavy, settings.coin, stats.count, 20) - }).then(() => exit(database)) - } else { - return settings.markets.enabled.reduce((complete, m, _, markets) => { - return promisify(db.check_market, m).then(([m, exists]) => { - complete++ - if (exists) { - return promisify(db.update_markets_db, m).then(err => { - if (err) debug(`${m}: ${err}`) - else debug(`${m} market data updated successfully.`) - if (complete === markets.length) exit() - return complete - }) - } - debug(`Error: entry for ${m} does not exist in markets db.`) - if (complete === markets.length) exit() - return complete - }) - }, 0) - } - }).catch(err => { - console.log(err) - console.log(`Unable to connect to database: ${settings.dbsettings.uri}.`) - console.log(`With options: ${prettyPrint(settings.dbsettings.options, null, 2)}`) - console.log('Aborting') - return exit(database) - }) + debug(`Error: entry for ${m} does not exist in markets db.`) + if (complete === markets.length) exit() + return complete + }) + }, 0) + } } -try { - main() -} catch (err) { - console.log(`An error occurred: ${prettyPrint(err)}`) +main().catch(err => { + console.log(`An error occurred: ${err}`) exit(database) -} +}) diff --git a/views/block.jade b/views/block.jade index 2ce7ba956..6251eac5b 100644 --- a/views/block.jade +++ b/views/block.jade @@ -25,8 +25,6 @@ block content th #{settings.locale.height} th #{settings.locale.difficulty} th #{settings.locale.confirmations} - if settings.heavy == true - th Vote th.hidden-xs #{settings.locale.size} (kB) th.hidden-xs #{settings.locale.bits} th.hidden-xs #{settings.locale.nonce} @@ -36,10 +34,8 @@ block content tr.success - var block_size = block.size/1024 td #{block.height} - td #{block.difficulty.toFixed(4)} + td #{parseFloat(block.difficulty).toFixed(4)} td #{block.confirmations} - if settings.heavy == true - td #{block.vote} td.hidden-xs #{block_size.toFixed(2)} td.hidden-xs #{block.bits} td.hidden-xs #{block.nonce} @@ -49,10 +45,8 @@ block content tr.danger - var block_size = block.size/1024 td #{block.height} - td #{block.difficulty.toFixed(4)} + td #{parseFloat(block.difficulty).toFixed(4)} td #{block.confirmations} - if settings.heavy == true - td #{block.vote} td.hidden-xs #{block_size.toFixed(2)} td.hidden-xs #{block.bits} td.hidden-xs #{block.nonce} @@ -61,10 +55,8 @@ block content tr.warning - var block_size = block.size/1024 td #{block.height} - td #{block.difficulty.toFixed(4)} + td #{parseFloat(block.difficulty).toFixed(4)} td #{block.confirmations} - if settings.heavy == true - td #{block.vote} td.hidden-xs #{block_size.toFixed(2)} td.hidden-xs #{block.bits} td.hidden-xs #{block.nonce} diff --git a/views/index.jade b/views/index.jade index aa82f28da..545a66240 100644 --- a/views/index.jade +++ b/views/index.jade @@ -3,42 +3,20 @@ extends layout block content script. $(document).ready(function () { - var stable = $('#block-table').dataTable( { - autoWidth: true, - searching: true, - ordering: false, - responsive: true, - lengthChange: false, - processing: true, - paging: false, - info: false, - ajax: { - url: '/ext/summary', - dataSrc: function (json) { - json.data[0]['height'] = "" + json.data[0]['height'] + "" - return json.data - } - }, - columns: [ - { data: 'blockcount', width: '8%' }, - { data: 'difficulty', width: '10%' }, - //- { data: 'size', width:'10%' }, - //- { data: 'txs', width: '10%' }, - { data: 'supply', width: '15%' }, - //- { data: 'time', width: '20%' }, - ] - }) var btable = $('#blocks-table').dataTable({ autoWidth: true, searching: false, ordering: false, responsive: true, lengthChange: true, - processing: true, + processing: parseInt(#{ui_interval}) > 10000, // only display loading indicator if update interval is long enough + language: { + processing: 'Loading...' + }, serverSide: true, ajax: function (data, cb, settings) { $.ajax({ - url: `/ext/getblocks/${data.start}/${data.start + data.length}?flds=summary&reverse=true&strip=true` + url: `/ext/getblocks/${data.start + 1}/${data.start + data.length}?flds=summary&reverse=true&strip=true` }).done((res) => { cb({ draw: data.draw, @@ -53,16 +31,15 @@ block content }) }, columns: [ - { data: 'height', width: '15%' }, - { data: 'hash', width: '45%' }, - { data: 'nTx', width: '10%' }, - { data: 'timestamp', width: '20%' }, + { data: 'height', width: '12%' }, + { data: 'hash', width: '48%' }, + { data: 'nTx', width: '8%' }, + { data: 'timestamp', width: '24%' }, ] }) setInterval(function () { - stable.api().ajax.reload(null, false) btable.api().ajax.reload(null, false) - }, 30000) + }, parseInt(#{ui_interval}) || 30000) }); .row .col-md-12 @@ -79,7 +56,7 @@ block content .panel.panel-default .panel-heading strong #{settings.locale.ex_latest_blocks} - table#blocks-table.table.table-bordered.table-striped + table#blocks-table.table.table-bordered.table-striped(style='font-family: "B612 Mono"') thead tr th.text-center #{settings.locale.height} diff --git a/views/info.jade b/views/info.jade index 079d7389f..7dcfd0283 100644 --- a/views/info.jade +++ b/views/info.jade @@ -44,43 +44,7 @@ block content :markdown * **getnetworkhashps** *#{settings.locale.api_getnetworkhashps}* - [#{address}/api/getnetworkhashps](/api/getnetworkhashps) - - - - if settings.heavy == true - :markdown - * **getmaxmoney** - *#{settings.locale.api_getmaxmoney}* - [#{address}/api/getmaxmoney](/api/getmaxmoney) - - * **getmaxvote** - *#{settings.locale.api_getmaxvote}* - [#{address}/api/getmaxvote](/api/getmaxvote) - - * **getvote** - *#{settings.locale.api_getvote}* - [#{address}/api/getvote](/api/getvote) - - * **getphase** - *#{settings.locale.api_getphase}* - [#{address}/api/getphase](/api/getphase) - - * **getreward** - *#{settings.locale.api_getreward}* - [#{address}/api/getreward](/api/getreward) - - * **getsupply** - *#{settings.locale.api_getsupply}* - [#{address}/api/getsupply](/api/getsupply) - - * **getnextrewardestimate** - *#{settings.locale.api_getnextrewardestimate}* - [#{address}/api/getnextrewardestimate](/api/getnextrewardestimate) - - * **getnextrewardwhenstr** - *#{settings.locale.api_getnextrewardwhenstr}* - [#{address}/api/getnextrewardwhenstr](/api/getnextrewardwhenstr) + [#{address}/api/getnetworkhashps](/api/getnetworkhashps) :markdown ------ @@ -104,15 +68,10 @@ block content *Returns current balance of given address* [#{address}/ext/getbalance/#{hashes.address}](/ext/getbalance/#{hashes.address}) - * **getlasttxs (/ext/getlasttxs?count=[number\_of\_txs]&minAmount=[min\_amount\_in\_#{settings.symbol}]&start=[most\_recent\_tx\_objectid])** - *Returns last [count] transactions with amounts (measured in #{settings.symbol}) greater than [minAmount]. Start is mainly used for paging results such that if specified, only transactions with objectIds less than [start] will be returned. Since objectIds are created according to when the transaction was added to the database, they essentially serve as a unique timestamp to query by.* - *Note: returned values are in satoshis* - [#{address}/ext/getlasttxs?count=10&minAmount=5](/ext/getlasttxs?count=10&minAmount=5) - - * **getblocks (/ext/getblocks/start/end?flds=[fields]&reverse=[true|false]&strip=[true|false])** - *Returns a list of blocks found from [start] to [end] block height (inclusive, indexed from 1). \[reverse\] can be set to read from the most recent blocks first (e.g. /ext/getblocks/1/10?reverse=true will return the 10 most recent blocks). A list of length end - start will always be returned and blocks not found will simply be set to null, however if [strip] is true, all invalid blockheights will be removed from the returned results.* - *[flds] is a list of fields to return, if set to "summary" it will only return block info, ["tx"] is commonly used to only return transactions in the block.* - [#{address}/ext/getblocks/1/10](/ext/getblocks/1/10) + * **getblocks (/ext/getblocks/start/end?flds=[fields]&reverse=[true|false])** + *Returns a list of blocks found from [start] to [end] block height (inclusive, indexed from 1). \[reverse\] can be set to read from the most recent blocks first (e.g. /ext/getblocks/1/10?reverse=true will return the 10 most recent blocks). A list of all blocks found within the specified height range will be returned.* + *[flds] is a list of fields to return, if set to "summary" it will only return block info, "fulltx" is commonly used to only return the fully decoded transactions in the block.* + [#{address}/ext/getblocks/0/10](/ext/getblocks/1/10) ------ diff --git a/views/layout.jade b/views/layout.jade index 091a9a1bd..8b7d4e4cc 100644 --- a/views/layout.jade +++ b/views/layout.jade @@ -6,6 +6,7 @@ html link(rel='stylesheet', href='/vendor/jqplot/jquery.jqplot.css') link(rel='stylesheet', href='//cdn.datatables.net/plug-ins/725b2a2115b/integration/bootstrap/3/dataTables.bootstrap.css') link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css') + link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=B612+Mono') link(rel='stylesheet', href='/stylesheets/style.css') script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js') script(src='//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js') @@ -53,7 +54,7 @@ html }); setInterval( function() { update_stats(); - }, 30000); + }, parseInt(#{ui_interval}) || 30000); update_stats(); }); body @@ -97,11 +98,6 @@ html a.navbar-link(href='/') span.glyphicon.glyphicon-search span.menu-text #{settings.locale.menu_explorer} - if settings.heavy == true - li#reward - a.navbar-link(href='/reward') - span.fa.fa-star - span.menu-text #{settings.locale.menu_reward} if settings.display.movement == true li#movement a.navbar-link.loading(href='/movement') diff --git a/views/reward.jade b/views/reward.jade deleted file mode 100644 index 93eccf381..000000000 --- a/views/reward.jade +++ /dev/null @@ -1,119 +0,0 @@ -extends layout - -block content - .row(style='margin-top:5px;') - .col-md-12(style='text-align:center;') - img(src='/images/logo.png' style='width:80px;margin: 0px auto 15px auto;') - .row - .col-xs-12.col-md-10.col-md-offset-1 - .panel.panel-default.panel-address-summary - .panel-heading(style='position:relative;') - strong #{settings.locale.heavy_title} (#{settings.symbol}) - - table.table.table-bordered.table-striped.summary-table - thead - tr - th #{settings.locale.ex_supply} (#{settings.symbol}) - th #{settings.locale.heavy_cap} (#{settings.symbol}) - th #{settings.locale.heavy_phase} - th #{settings.locale.heavy_maxvote} - th #{settings.locale.heavy_reward} - th #{settings.locale.heavy_estnext} - tbody - tr - td - =heavy.supply - td - =heavy.cap - td - =heavy.phase - td - =heavy.maxvote - td - =heavy.reward - td - =heavy.estnext - .row - .col-md-10.col-md-offset-1 - .panel.panel-defual - .panel-body - .col-md-3 - center - canvas(id="myChart2", width="150", height="150") - script. - var ctx = document.getElementById("myChart2").getContext("2d"); - var data = [ - { - value: ((#{stats.count}/3600)%1)*100, - //color: "rgba(151,187,205,0.5)" - color: "rgba(92,184,92,1.0)" - }, - { - value : (1-((#{stats.count}/3600)%1))*100, - color : "#222" - } - ] - new Chart(ctx).Doughnut(data); - h5 #{settings.locale.heavy_changein} - h5 - =heavy.nextin - - form - table.table - thead - tbody - tr - th #{settings.locale.heavy_key} - td - tr - th #{settings.locale.heavy_vote} - td - div(style="width:20px;height:20px;background-color:#428bca") - tr - th #{settings.locale.heavy_current} - td - div(style="width:20px;height:20px;background-color:#222") - tr - th #{settings.locale.heavy_estnext} - td - div(style="width:20px;height:20px;background-color:rgba(92,184,92,1.0)") - - .col-md-9 - center - .row - strong #{settings.locale.heavy_lastxvotes} - .row - canvas(id="myChart", width="800", height="300", style="margin-left:-30px;margin-top:30px;") - script. - - var ctx = document.getElementById("myChart").getContext("2d"); - var options = { - scaleOverride : true, - scaleSteps : 8, - scaleStepWidth : 1, - scaleStartValue : 0, - bezierCurve : false, - } - var data = { - labels : [#{votes[0].count},#{votes[1].count},#{votes[2].count},#{votes[3].count},#{votes[4].count},#{votes[5].count},#{votes[6].count},#{votes[7].count},#{votes[8].count},#{votes[9].count},#{votes[10].count},#{votes[11].count},#{votes[12].count},#{votes[13].count},#{votes[14].count},#{votes[15].count},#{votes[16].count},#{votes[17].count},#{votes[18].count},#{votes[19].count}], - datasets : [ - { - fillColor : "rgba(66,139,202,0.5)", - strokeColor : "rgba(66,139,202,0.8)", - pointColor : '#428bca', - pointStrokeColor : "#fff", - data : [#{votes[0].vote},#{votes[1].vote},#{votes[2].vote},#{votes[3].vote},#{votes[4].vote},#{votes[5].vote},#{votes[6].vote},#{votes[7].vote},#{votes[8].vote},#{votes[9].vote},#{votes[10].vote},#{votes[11].vote},#{votes[12].vote},#{votes[13].vote},#{votes[14].vote},#{votes[15].vote},#{votes[16].vote},#{votes[17].vote},#{votes[18].vote},#{votes[19].vote}] - }, - { - fillColor : "rgba(151,187,205,0.0)", - strokeColor : '#222', - pointColor : "rgba(0,0,0,0)", - pointStrokeColor : "rgba(0,0,0,0.0)", - data : [#{votes[0].reward},#{votes[1].reward},#{votes[2].reward},#{votes[3].reward},#{votes[4].reward},#{votes[5].reward},#{votes[6].reward},#{votes[7].reward},#{votes[8].reward},#{votes[9].reward},#{votes[10].reward},#{votes[11].reward},#{votes[12].reward},#{votes[13].reward},#{votes[14].reward},#{votes[15].reward},#{votes[16].reward},#{votes[17].reward},#{votes[18].reward},#{votes[19].reward}] - }, - ] - } - var myNewChart = new Chart(ctx).Line(data,options); - - -