diff --git a/bin/instance b/bin/instance index aa5667f..0824892 100644 --- a/bin/instance +++ b/bin/instance @@ -23,9 +23,12 @@ db.connect(dbString, function() { server.close(() => { var mongoose = require('mongoose'); - mongoose.connection.close(false, () => { + mongoose.connection.close(false).then(() => { // close the main process now that all http and database connections have closed process.exit(0); + }).catch((err) => { + console.log(err); + process.exit(1); }); }); }); diff --git a/lib/database.js b/lib/database.js index e7e7a4c..0548b30 100644 --- a/lib/database.js +++ b/lib/database.js @@ -19,38 +19,38 @@ var mongoose = require('mongoose'), function find_address(hash, caseSensitive, cb) { if (caseSensitive) { // faster search but only matches exact string including case - Address.findOne({a_id: hash}, function(err, address) { + Address.findOne({a_id: hash}).then((address) => { if (address) return cb(address); else return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } else { // slower search but matches exact string ignoring case - Address.findOne({a_id: {$regex: '^' + hash + '$', $options: 'i'}}, function(err, address) { + Address.findOne({a_id: {$regex: '^' + hash + '$', $options: 'i'}}).then((address) => { if (address) return cb(address); else return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } } -function find_address_tx(address, hash, cb) { - AddressTx.findOne({a_id: address, txid: hash}, function(err, address_tx) { - if (address_tx) - return cb(address_tx); - else - return cb(); - }); -} - function find_richlist(coin, cb) { - Richlist.findOne({coin: coin}, function(err, richlist) { + Richlist.findOne({coin: coin}).then((richlist) => { if (richlist) return cb(richlist); else return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } @@ -76,41 +76,41 @@ function update_address(hash, blockheight, txid, amount, type, cb) { }, { new: true, upsert: true - }, function (err, address) { - if (err) - return cb(err); - else { - if (hash != 'coinbase') { - AddressTx.findOneAndUpdate({a_id: hash, txid: txid}, { - $inc: { - amount: addr_inc.balance - }, - $set: { - a_id: hash, - blockindex: blockheight, - txid: txid - } - }, { - new: true, - upsert: true - }, function (err,addresstx) { - if (err) - return cb(err); - else - return cb(); - }); - } else + }).then((address) => { + if (hash != 'coinbase') { + AddressTx.findOneAndUpdate({a_id: hash, txid: txid}, { + $inc: { + amount: addr_inc.balance + }, + $set: { + a_id: hash, + blockindex: blockheight, + txid: txid + } + }, { + new: true, + upsert: true + }).then((addresstx) => { return cb(); - } + }).catch((err) => { + return cb(err); + }); + } else + return cb(); + }).catch((err) => { + return cb(err); }); } function find_tx(txid, cb) { - Tx.findOne({txid: txid}, function(err, tx) { + Tx.findOne({txid: txid}).then((tx) => { if (tx) return cb(tx); else return cb(null); + }).catch((err) => { + console.log(err); + return cb(null); }); } @@ -127,41 +127,55 @@ function get_market_data(market, coin_symbol, pair_symbol, cb) { function check_add_db_field(model_obj, field_name, default_value, cb) { // determine if a particular field exists in a db collection - model_obj.findOne({[field_name]: {$exists: false}}, function(err, model_data) { + model_obj.findOne({[field_name]: {$exists: false}}).then((model_data) => { // check if field exists if (model_data) { // add field to all documents in the collection model_obj.updateMany({}, { $set: { [field_name]: default_value } - }, function() { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); } function check_rename_db_field(model_obj, old_field_name, new_field_name, cb) { // determine if a particular field exists in a db collection - model_obj.findOne({[old_field_name]: {$exists: false}}, function(err, model_data) { + model_obj.findOne({[old_field_name]: {$exists: false}}).then((model_data) => { // check if old field exists if (model_data) { // rename field model_obj.updateMany({}, { $rename: { [old_field_name]: new_field_name } - }, { multi: true, strict: false }, function() { + }, { multi: true, strict: false }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); } function hex_to_ascii(hex) { - var str = ''; - for (var i = 0; i < hex.length; i += 2) - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - return str; + var str = ''; + + for (var i = 0; i < hex.length; i += 2) + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + + return str; } function init_markets(cb) { @@ -259,13 +273,11 @@ module.exports = { connect: function(database, cb) { mongoose.set('strictQuery', true); - mongoose.connect(database, function(err) { - if (err) { - console.log('Error: Unable to connect to database: %s', database); - process.exit(999); - } - + mongoose.connect(database).then(() => { return cb(); + }).catch((err) => { + console.log('Error: Unable to connect to database: %s', err); + process.exit(999); }); }, @@ -278,7 +290,7 @@ module.exports = { if (address) { Address.updateOne({a_id: hash}, { name: claim_name - }, function() { + }).then(() => { // update claim name in richlist module.exports.update_richlist_claim_name(hash, claim_name, function() { // update claim name in masternode list @@ -286,6 +298,8 @@ module.exports = { return cb(''); }); }); + }).catch((err) => { + return cb(err); }); } else { // address is not valid or does not have any transactions @@ -329,9 +343,12 @@ module.exports = { Richlist.updateOne({coin: settings.coin.name}, { received: richlist.received, balance: richlist.balance - }, function() { + }).then(() => { // finished updating the claim label return cb(''); + }).catch((err) => { + console.log(err); + return cb(''); }); } else { // finished updating the claim label @@ -367,9 +384,12 @@ module.exports = { // save the updated masternode back to collection Masternode.updateOne({addr: hash}, { claim_name: claim_name - }, function() { + }).then(() => { // finished updating the claim label return cb(''); + }).catch((err) => { + console.log(err); + return cb(''); }); } else { // finished updating the claim label @@ -383,7 +403,7 @@ module.exports = { }, check_txes: function(cb) { - Tx.findOne({}, function(err, tx) { + Tx.findOne({}).then((tx) => { if (tx) { // collection has data // determine if tx_type field exists @@ -395,11 +415,14 @@ module.exports = { }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, check_stats: function(coin, cb) { - Stats.findOne({coin: coin}, function(err, stats) { + Stats.findOne({coin: coin}).then((stats) => { if (stats) { // collection has data // determine if last_usd_price field exists @@ -414,15 +437,21 @@ module.exports = { }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, get_stats: function(coin, cb) { - Stats.findOne({coin: coin}, function(err, stats) { + Stats.findOne({coin: coin}).then((stats) => { if (stats) return cb(stats); else return cb(null); + }).catch((err) => { + console.log(err); + return cb(null); }); }, @@ -436,14 +465,12 @@ module.exports = { orphan_current: 0 }); - newStats.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else { - console.log("Initial stats entry created for %s", coin); - return cb(); - } + newStats.save().then(() => { + console.log("Initial stats entry created for %s", coin); + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } else return cb(); @@ -475,28 +502,40 @@ module.exports = { if (list == 'received') { // update 'received' richlist data - Address.find({a_id: { $nin: burn_addresses }}, 'a_id name balance received').sort({received: 'desc'}).limit(total_addresses).exec(function(err, addresses) { + Address.find({a_id: { $nin: burn_addresses }}, 'a_id name balance received').sort({received: 'desc'}).limit(total_addresses).exec().then((addresses) => { Richlist.updateOne({coin: settings.coin.name}, { received: addresses - }, function() { + }).then(() => { + return cb(); + }).catch((err) => { + console.log(err); return cb(); }); + }).catch((err) => { + console.log(err); + return cb(); }); } else { // update 'balance' richlist data // check if burned addresses are in use and if it is necessary to track burned balances if (settings.richlist_page.burned_coins.addresses == null || settings.richlist_page.burned_coins.addresses.length == 0 || !settings.richlist_page.burned_coins.include_burned_coins_in_distribution) { // update 'balance' richlist data by filtering burned coin addresses immidiately - Address.find({a_id: { $nin: burn_addresses }}, 'a_id name balance received').sort({balance: 'desc'}).limit(total_addresses).exec(function(err, addresses) { + Address.find({a_id: { $nin: burn_addresses }}, 'a_id name balance received').sort({balance: 'desc'}).limit(total_addresses).exec().then((addresses) => { Richlist.updateOne({coin: settings.coin.name}, { balance: addresses - }, function() { + }).then(() => { + return cb(); + }).catch((err) => { + console.log(err); return cb(); }); + }).catch((err) => { + console.log(err); + return cb(); }); } else { // do not omit burned addresses from database query. instead, increase the limit of returned addresses and manually remove each burned address that made it into the rich list after recording the burned balance - Address.find({}, 'a_id name balance received').sort({balance: 'desc'}).limit(total_addresses + burn_addresses.length).exec(function(err, addresses) { + Address.find({}, 'a_id name balance received').sort({balance: 'desc'}).limit(total_addresses + burn_addresses.length).exec().then((addresses) => { var return_addresses = []; var burned_balance = 0.0; @@ -516,9 +555,15 @@ module.exports = { Richlist.updateOne({coin: settings.coin.name}, { balance: return_addresses, burned: burned_balance - }, function() { + }).then(() => { + return cb(); + }).catch((err) => { + console.log(err); return cb(); }); + }).catch((err) => { + console.log(err); + return cb(); }); } } @@ -584,25 +629,27 @@ module.exports = { // check if min is greater than zero if (min > 0) { // min is greater than zero which means we must pull record count from the txes collection - Tx.find({'total': {$gte: min}}).countDocuments(function(err, count) { + Tx.find({'total': {$gte: min}}).countDocuments().then((count) => { // get last transactions where there is at least 1 vout - Tx.find({'total': {$gte: min}, 'vout': { $gte: { $size: 1 }}}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec(function(err, txs) { - if (err) - return cb(err); - else - return cb(txs, count); + Tx.find({'total': {$gte: min}, 'vout': { $gte: { $size: 1 }}}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec().then((txs) => { + return cb(txs, count); + }).catch((err) => { + return cb(err); }); + }).catch((err) => { + return cb(err); }); } else { // min is zero (shouldn't ever be negative) which means we must pull record count from the coinstats collection (pulling from txes could potentially take a long time because it would include coinbase txes) - Stats.findOne({coin: settings.coin.name}, function(err, stats) { + Stats.findOne({coin: settings.coin.name}).then((stats) => { // Get last transactions where there is at least 1 vout - Tx.find({'total': {$gte: min}, 'vout': { $gte: { $size: 1 }}}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec(function(err, txs) { - if (err) - return cb(err); - else - return cb(txs, stats.txes); + Tx.find({'total': {$gte: min}, 'vout': { $gte: { $size: 1 }}}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec().then((txs) => { + return cb(txs, stats.txes); + }).catch((err) => { + return cb(err); }); + }).catch((err) => { + return cb(err); }); } }, @@ -610,66 +657,60 @@ module.exports = { get_address_txs_ajax: function(hash, start, length, cb) { var totalCount = 0; - AddressTx.find({a_id: hash}).countDocuments(function(err, count) { - if (err) - return cb(err); - else { - totalCount = count; + AddressTx.find({a_id: hash}).countDocuments().then((count) => { + totalCount = count; - AddressTx.aggregate([ - { $match: { a_id: hash } }, - { $sort: {blockindex: -1} }, - { $skip: Number(start) }, - { - $group: { - _id: '', - balance: { $sum: '$amount' } - } - }, - { - $project: { - _id: 0, - balance: '$balance' - } - }, - { $sort: {blockindex: -1} } - ], function (err,balance_sum) { - if (err) - return cb(err); - else { - AddressTx.find({a_id: hash}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec(function (err, address_tx) { - if (err) - return cb(err); - else { - var txs = []; - var count = address_tx.length; - var running_balance = balance_sum.length > 0 ? balance_sum[0].balance : 0; - var txs = []; - - lib.syncLoop(count, function (loop) { - var i = loop.iteration(); - - find_tx(address_tx[i].txid, function (tx) { - if (tx && !txs.includes(tx)) { - tx.balance = running_balance; - txs.push(tx); - loop.next(); - } else if (!txs.includes(tx)) { - txs.push("1. Not found"); - loop.next(); - } else - loop.next(); - - running_balance = running_balance - address_tx[i].amount; - }); - }, function () { - return cb(txs, totalCount); - }); - } - }); + AddressTx.aggregate([ + { $match: { a_id: hash } }, + { $sort: {blockindex: -1} }, + { $skip: Number(start) }, + { + $group: { + _id: '', + balance: { $sum: '$amount' } } + }, + { + $project: { + _id: 0, + balance: '$balance' + } + }, + { $sort: {blockindex: -1} } + ]).then((balance_sum) => { + AddressTx.find({a_id: hash}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec().then((address_tx) => { + var txs = []; + var count = address_tx.length; + var running_balance = balance_sum.length > 0 ? balance_sum[0].balance : 0; + var txs = []; + + lib.syncLoop(count, function (loop) { + var i = loop.iteration(); + + find_tx(address_tx[i].txid, function (tx) { + if (tx && !txs.includes(tx)) { + tx.balance = running_balance; + txs.push(tx); + loop.next(); + } else if (!txs.includes(tx)) { + txs.push("1. Not found"); + loop.next(); + } else + loop.next(); + + running_balance = running_balance - address_tx[i].amount; + }); + }, function () { + return cb(txs, totalCount); + }); + }).catch((err) => { + return cb(err); }); - } + }).catch((err) => { + return cb(err); + }); + }).catch((err) => { + return cb(err); }); }, @@ -680,31 +721,35 @@ module.exports = { pair_symbol: pair_symbol }); - newMarkets.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else { - console.log("Initial market entry created for %s: %s", market, coin_symbol +'/' + pair_symbol); - return cb(); - } + newMarkets.save().then(() => { + console.log("Initial market entry created for %s: %s", market, coin_symbol +'/' + pair_symbol); + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, // check if market data exists for a given market and trading pair check_market: function(market, coin_symbol, pair_symbol, cb) { - Markets.findOne({market: market, coin_symbol: coin_symbol, pair_symbol: pair_symbol}, function(err, exists) { + Markets.findOne({market: market, coin_symbol: coin_symbol, pair_symbol: pair_symbol}).then((exists) => { return cb(market, exists); + }).catch((err) => { + console.log(err); + return cb(market, false); }); }, // gets market data for given market and trading pair get_market: function(market, coin_symbol, pair_symbol, cb) { - Markets.findOne({market: market, coin_symbol: coin_symbol, pair_symbol: pair_symbol}, function(err, data) { + Markets.findOne({market: market, coin_symbol: coin_symbol, pair_symbol: pair_symbol}).then((data) => { if (data) return cb(data); else return cb(null); + }).catch((err) => { + console.log(err); + return cb(null); }); }, @@ -716,14 +761,12 @@ module.exports = { coin: coin }); - newRichlist.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else { - console.log("Initial richlist entry created for %s", coin); - return cb(); - } + newRichlist.save().then(() => { + console.log("Initial richlist entry created for %s", coin); + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } else return cb(); @@ -731,21 +774,27 @@ module.exports = { // drops richlist data for given coin delete_richlist: function(coin, cb) { - Richlist.findOneAndRemove({coin: coin}, function(err, exists) { + Richlist.findOneAndRemove({coin: coin}).then((exists) => { if (exists) return cb(true); else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, // checks richlist data exists for given coin check_richlist: function(coin, cb) { - Richlist.findOne({coin: coin}, function(err, exists) { + Richlist.findOne({coin: coin}).then((exists) => { if (exists) return cb(true); else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, @@ -754,32 +803,36 @@ module.exports = { coin: coin }); - newHeavy.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else { - console.log("Initial heavycoin entry created for %s", coin); - return cb(); - } + newHeavy.save().then(() => { + console.log("Initial heavycoin entry created for %s", coin); + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, check_heavy: function(coin, cb) { - Heavy.findOne({coin: coin}, function(err, exists) { + Heavy.findOne({coin: coin}).then((exists) => { if (exists) return cb(true); else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, get_heavy: function(coin, cb) { - Heavy.findOne({coin: coin}, function(err, heavy) { + Heavy.findOne({coin: coin}).then((heavy) => { if (heavy) return cb(heavy); else return cb(null); + }).catch((err) => { + console.log(err); + return cb(null); }); }, @@ -868,12 +921,15 @@ module.exports = { maxvote: (maxvote ? maxvote : 0), nextin: (nextin ? nextin : 'N/A'), votes: newVotes - }, function() { + }).then(() => { // update reward_last_updated value module.exports.update_last_updated_stats(settings.coin.name, { reward_last_updated: Math.floor(new Date() / 1000) }, function (new_cb) { console.log('Heavycoin update complete'); return cb(); }); + }).catch((err) => { + console.log(err); + return cb(); }); }); }); @@ -890,7 +946,7 @@ module.exports = { // height: current block height update_network_history: function(height, cb) { // lookup network history data for this block height - NetworkHistory.findOne({blockindex: height}, function(err, network_hist) { + NetworkHistory.findOne({blockindex: height}).then((network_hist) => { // check if there is already network history data for this block height if (!network_hist) { // lookup network hashrate @@ -922,36 +978,42 @@ module.exports = { }); // save the new network history record - newNetworkHistory.save(function(err) { - // check for errors - if (err) { - console.log('Error updating network history: ' + err); - return cb(); - } else { - // get the count of network history records - NetworkHistory.find({}).countDocuments(function(err, count) { - // read maximum allowed records from settings - let max_records = settings.network_history.max_saved_records; + newNetworkHistory.save().then(() => { + // get the count of network history records + NetworkHistory.find({}).countDocuments().then((count) => { + // read maximum allowed records from settings + let max_records = settings.network_history.max_saved_records; - // check if the current count of records is greater than the maximum allowed - if (count > max_records) { - // prune network history records to keep collection small and quick to access - NetworkHistory.find().select('blockindex').sort({blockindex: 1}).limit(count - max_records).exec(function(err, records) { - // create a list of the oldest network history ids that will be deleted - const ids = records.map((doc) => doc.blockindex); + // check if the current count of records is greater than the maximum allowed + if (count > max_records) { + // prune network history records to keep collection small and quick to access + NetworkHistory.find().select('blockindex').sort({blockindex: 1}).limit(count - max_records).exec().then((records) => { + // create a list of the oldest network history ids that will be deleted + const ids = records.map((doc) => doc.blockindex); - // delete old network history records - NetworkHistory.deleteMany({blockindex: {$in: ids}}, function(err) { - console.log('Network history update complete'); - return cb(); - }); + // delete old network history records + NetworkHistory.deleteMany({blockindex: {$in: ids}}).then(() => { + console.log('Network history update complete'); + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); - } else { - console.log('Network history update complete'); + }).catch((err) => { + console.log(err); return cb(); - } - }); - } + }); + } else { + console.log('Network history update complete'); + return cb(); + } + }).catch((err) => { + console.log(err); + return cb(); + }); + }).catch((err) => { + console.log('Error updating network history: ' + err); + return cb(); }); }); }); @@ -959,6 +1021,9 @@ module.exports = { // skip saving network history data when the block hasn't moved since saving last time return cb(); } + }).catch((err) => { + console.log(err); + return cb(); }); }, @@ -976,20 +1041,26 @@ module.exports = { sells: obj.sells, history: obj.trades, summary: obj.stats - }, function() { + }).then(() => { // check if this is the default market and trading pair if (market == settings.markets_page.default_exchange.exchange_name && settings.markets_page.default_exchange.trading_pair.toUpperCase() == coin_symbol.toUpperCase() + '/' + pair_symbol.toUpperCase()) { // this is the default market so update the last price stats Stats.updateOne({coin: settings.coin.name}, { last_price: obj.stats.last - }, function() { + }).then(() => { // finished updating market data return cb(null); + }).catch((err) => { + console.log(err); + return cb(null); }); } else { // this is not the default market so we are finished updating market data return cb(null); } + }).catch((err) => { + console.log(err); + return cb(null); }); } else { // an error occurred with getting market data so return the error msg @@ -1019,14 +1090,20 @@ module.exports = { // check for errors if (err == null) { // get current stats - Stats.findOne({coin: settings.coin.name}, function(err, stats) { + Stats.findOne({coin: settings.coin.name}).then((stats) => { // update the last usd price Stats.updateOne({coin: settings.coin.name}, { last_usd_price: (last_usd * stats.last_price) - }, function() { + }).then(() => { // last usd price updated successfully return cb(null); + }).catch((err) => { + // return error msg + return cb(err); }); + }).catch((err) => { + // return error msg + return cb(err); }); } else { // return error msg @@ -1060,17 +1137,14 @@ module.exports = { lib.get_supply(function (supply) { lib.get_connectioncount(function (connections) { - Stats.findOne({coin: coin}, function(err, stats) { + Stats.findOne({coin: coin}).then((stats) => { if (stats) { Stats.updateOne({coin: coin}, { coin: coin, count : count, supply: (supply ? supply : 0), connections: (connections ? connections : 0) - }, function(err) { - if (err) - console.log("Error during stats update: %s", err); - + }).then(() => { return cb({ coin: coin, count : count, @@ -1081,11 +1155,17 @@ module.exports = { orphan_index: (stats.orphan_index ? stats.orphan_index : 0), orphan_current: (stats.orphan_current ? stats.orphan_current : 0) }); + }).catch((err) => { + console.log("Error during stats update: %s", err); + return cb(false); }); } else { console.log("Error during stats update: %s", (err ? err : 'Cannot find stats collection')); return cb(false); } + }).catch((err) => { + console.log(err); + return cb(false); }); }); }); @@ -1095,59 +1175,55 @@ module.exports = { create_peer: function(params, cb) { var newPeer = new Peers(params); - newPeer.save(function(err) { - if (err) { - console.log(err); - return cb(); - } else - return cb(); + newPeer.save().then(() => { + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, find_peer: function(address, port, cb) { - Peers.findOne({address: address, port: port}, function(err, peer) { - if (err) - return cb(null); - else { - if (peer) - return cb(peer); - else - return cb (null) - } + Peers.findOne({address: address, port: port}).then((peer) => { + if (peer) + return cb(peer); + else + return cb (null) + }).catch((err) => { + console.log(err); + return cb(null); }); }, drop_peer: function(address, port, cb) { - Peers.deleteOne({address: address, port: port}, function(err) { - if (err) { - console.log(err); - return cb(); - } else - return cb(); + Peers.deleteOne({address: address, port: port}).then(() => { + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, drop_peers: function(cb) { - Peers.deleteMany({}, function(err) { - if (err) { - console.log(err); - return cb(); - } else - return cb(); + Peers.deleteMany({}).then(() => { + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, get_peers: function(cb) { - Peers.find().sort({address: 1, protocol: -1, port: 1}).exec(function (err, peers) { - if (err) - return cb([]); - else - return cb(peers); + Peers.find().sort({address: 1, protocol: -1, port: 1}).exec().then((peers) => { + return cb(peers); + }).catch((err) => { + console.log(err); + return cb([]); }); }, check_masternodes: function(cb) { - Masternode.findOne({}, function(err, masternode) { + Masternode.findOne({}).then((masternode) => { if (masternode) { // collection has data // determine if ip_address field exists @@ -1159,6 +1235,9 @@ module.exports = { }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, @@ -1231,21 +1310,19 @@ module.exports = { if (add) { // add new masternode to collection - mn.save(function (err) { - if (err) { - console.log(err); - return cb(false); - } else - return cb(true); + mn.save().then(() => { + return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else { // update existing masternode in local collection - Masternode.updateOne({ txhash: (masternode.proTxHash != null ? masternode.proTxHash : masternode.txhash) }, masternode, function (err) { - if (err) { - console.log(err); - return cb(false); - } else - return cb(true); + Masternode.updateOne({ txhash: (masternode.proTxHash != null ? masternode.proTxHash : masternode.txhash) }, masternode).then(() => { + return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } } @@ -1253,36 +1330,34 @@ module.exports = { // find masternode by txid find_masternode: function (txhash, cb) { - Masternode.findOne({ txhash: txhash }, function (err, masternode) { - if (err) + Masternode.findOne({ txhash: txhash }).then((masternode) => { + if (masternode) + return cb(masternode); + else return cb(null); - else { - if (masternode) - return cb(masternode); - else - return cb(null); - } + }).catch((err) => { + console.log(err); + return cb(null); }); }, // remove masternodes older than 24 hours remove_old_masternodes: function (cb) { - Masternode.deleteMany({ lastseen: { $lte: (Math.floor(Date.now() / 1000) - 86400) } }, function (err) { - if (err) { - console.log(err); - return cb(); - } else - return cb(); + Masternode.deleteMany({ lastseen: { $lte: (Math.floor(Date.now() / 1000) - 86400) } }).then(() => { + return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }, // get the list of masternodes from local collection get_masternodes: function (cb) { - Masternode.find({}, function (err, masternodes) { - if (err) - return cb([]); - else - return cb(masternodes); + Masternode.find({}).then((masternodes) => { + return cb(masternodes); + }).catch((err) => { + console.log(err); + return cb([]); }); }, @@ -1296,12 +1371,11 @@ module.exports = { { $match: { "vout.addresses": { $in: [mnPayees] } }} - ], function(err, data) { - if (err) { - console.log(err); - return cb(null); - } else - return cb(data); + ]).then((data) => { + return cb(data); + }).catch((err) => { + console.log(err); + return cb(null); }); }, @@ -1316,12 +1390,11 @@ module.exports = { "vout.addresses": { $in: [mnPayees] } }}, { $group: { _id: null, total: { $sum: "$vout.amount" } } } - ], function(err, data) { - if (err) { - console.log(err); - return cb(null); - } else - return cb((data.length > 0 ? data[0].total / 100000000 : 0)); + ]).then((data) => { + return cb((data.length > 0 ? data[0].total / 100000000 : 0)); + }).catch((err) => { + console.log(err); + return cb(null); }); }, @@ -1331,43 +1404,61 @@ module.exports = { // update blockchain last updated date Stats.updateOne({ coin: coin }, { blockchain_last_updated: param.blockchain_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else if (param.reward_last_updated) { // update reward last updated date Stats.updateOne({ coin: coin }, { reward_last_updated: param.reward_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else if (param.masternodes_last_updated) { // update masternode last updated date Stats.updateOne({ coin: coin }, { masternodes_last_updated: param.masternodes_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else if (param.network_last_updated) { // update network last updated date Stats.updateOne({ coin: coin }, { network_last_updated: param.network_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else if (param.richlist_last_updated) { // update richlist last updated date Stats.updateOne({ coin: coin }, { richlist_last_updated: param.richlist_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else if (param.markets_last_updated) { // update markets last updated date Stats.updateOne({ coin: coin }, { markets_last_updated: param.markets_last_updated - }, function () { + }).then(() => { return cb(true); + }).catch((err) => { + console.log(err); + return cb(false); }); } else { // invalid option @@ -1431,13 +1522,16 @@ module.exports = { get_network_chart_data: function(cb) { // lookup all network history data for populating network charts - NetworkHistory.find().sort({blockindex: 1}).exec(function (err, data) { + NetworkHistory.find().sort({blockindex: 1}).exec().then((data) => { return cb(data); + }).catch((err) => { + console.log(err); + return cb(null); }); }, check_networkhistory: function(cb) { - NetworkHistory.findOne({}, function(err, networkhistory) { + NetworkHistory.findOne({}).then((networkhistory) => { if (networkhistory) { // collection has data // determine if the difficulty field exists @@ -1449,6 +1543,9 @@ module.exports = { }); } else return cb(false); + }).catch((err) => { + console.log(err); + return cb(false); }); }, @@ -1577,11 +1674,10 @@ module.exports = { op_return: op_return }); - newTx.save(function(err) { - if (err) - return cb(err, false); - else - return cb(null, vout.length > 0); + newTx.save().then(() => { + return cb(null, vout.length > 0); + }).catch((err) => { + return cb(err, false); }); }); }); @@ -1596,14 +1692,17 @@ module.exports = { // get the list of orphans from local collection get_orphans: function(start, length, cb) { // get the count of orphaned blocks - Orphans.find({}).countDocuments(function(err, count) { + Orphans.find({}).countDocuments().then((count) => { // get the actual orphaned block data - Orphans.find({}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec(function(err, orphans) { - if (err) - return cb([], count); - else - return cb(orphans, count); + Orphans.find({}).sort({blockindex: -1}).skip(Number(start)).limit(Number(length)).exec().then((orphans) => { + return cb(orphans, count); + }).catch((err) => { + console.log(err); + return cb([], count); }); + }).catch((err) => { + console.log(err); + return cb([], 0); }); }, diff --git a/lib/explorer.js b/lib/explorer.js index 8bb1170..3694a16 100644 --- a/lib/explorer.js +++ b/lib/explorer.js @@ -10,11 +10,14 @@ const client = new onode.Client(settings.wallet); // returns coinbase total sent as current coin supply function coinbase_supply(cb) { - Address.findOne({a_id: 'coinbase'}, function(err, address) { + Address.findOne({a_id: 'coinbase'}).then((address) => { if (address) return cb(address.sent); else return cb(0); + }).catch((err) => { + console.log(err); + return cb(0); }); } @@ -810,7 +813,7 @@ module.exports = { }, balance_supply: function(cb) { - Address.find({}, 'balance').where('balance').gt(0).exec(function(err, docs) { + Address.find({}, 'balance').where('balance').gt(0).exec().then((docs) => { var count = 0; module.exports.syncLoop(docs.length, function (loop) { @@ -821,6 +824,9 @@ module.exports = { }, function() { return cb(count); }); + }).catch((err) => { + console.log(err); + return cb(0); }); }, diff --git a/package.json b/package.json index 3b68df4..d020914 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,8 @@ "express": ">=4.18.1", "intl": "^1.2.5", "jsonminify": "^0.4.2", - "mongodb": "^4.7.0", - "mongoose": "^6.3.6", + "mongodb": "^5.4.0", + "mongoose": "^7.1.0", "morgan": ">=1.10.0", "postman-request": "^2.88.1-postman.31", "pug": "~3.0.2", diff --git a/scripts/benchmark.js b/scripts/benchmark.js index 6f20d39..bc10fb2 100644 --- a/scripts/benchmark.js +++ b/scripts/benchmark.js @@ -22,14 +22,9 @@ dbString = dbString + "/IQUIDUS-BENCHMARK"; mongoose.set('strictQuery', true); -mongoose.connect(dbString, function(err) { - if (err) { - console.log('Error: Unable to connect to database: %s', dbString); - exit(999); - } - - Tx.deleteMany({}, function(err) { - Address.deleteMany({}, function(err2) { +mongoose.connect(dbString).then(() => { + Tx.deleteMany({}).then(() => { + Address.deleteMany({}).then(() => { var s_timer = new Date().getTime(); // updates tx, address & richlist db's @@ -54,7 +49,7 @@ mongoose.connect(dbString, function(err) { Stats.updateOne({coin: coin}, { last: block_height - 1, txes: txes - }, function() {}); + }).then(() => {}); } else if (check_only) { console.log('Checking block ' + block_height + '...'); } @@ -64,7 +59,7 @@ mongoose.connect(dbString, function(err) { lib.get_block(blockhash, function(block) { if (block) { async.eachLimit(block.tx, task_limit_txs, function(txid, next_tx) { - Tx.findOne({txid: txid}, function(err, tx) { + Tx.findOne({txid: txid}).then((tx) => { if (tx) { setTimeout( function() { tx = null; @@ -86,6 +81,13 @@ mongoose.connect(dbString, function(err) { }, timeout); }); } + }).catch((err) => { + console.log(err); + + setTimeout( function() { + tx = null; + next_tx(); + }, timeout); }); }, function() { setTimeout( function() { @@ -112,7 +114,10 @@ mongoose.connect(dbString, function(err) { Stats.updateOne({coin: coin}, { last: end, txes: txes - }, function() { + }).then(() => { + return cb(); + }).catch((err) => { + console.log(err); return cb(); }); }); @@ -121,8 +126,8 @@ mongoose.connect(dbString, function(err) { update_tx_db(settings.coin.name, 1, COUNT, 0, settings.sync.update_timeout, false, function() { var e_timer = new Date().getTime(); - Tx.countDocuments({}, function(txerr, txcount) { - Address.countDocuments({}, function(aerr, acount) { + Tx.countDocuments({}).then((txcount) => { + Address.countDocuments({}).then((acount) => { var stats = { tx_count: txcount, address_count: acount, @@ -136,4 +141,7 @@ mongoose.connect(dbString, function(err) { }); }); }); +}).catch((err) => { + console.log('Error: Unable to connect to database: %s', dbString); + exit(999); }); \ No newline at end of file diff --git a/scripts/delete_database.js b/scripts/delete_database.js index 6e33c7d..dd71716 100644 --- a/scripts/delete_database.js +++ b/scripts/delete_database.js @@ -52,12 +52,15 @@ function finishExit(db, exitCode) { function drop_collection(mongoose, colName, cb) { // attempt to delete the collection - mongoose.connection.db.dropCollection(colName, function(err, result) { - if (err || !result) { + mongoose.connection.db.dropCollection(colName).then((result) => { + if (!result) { console.log(`Error: Unable to delete the ${colName} collection`); exit(mongoose, 1); } else return cb(true); + }).catch((err) => { + console.log(err); + exit(mongoose, 1); }); } @@ -95,49 +98,45 @@ rl.question('Are you sure you want to do this? [y/n]: ', function (deleteAnswer) mongoose.set('strictQuery', true); // connect to mongo database - mongoose.connect(dbString, function(err) { - if (err) { - console.log('Error: Unable to connect to database: %s', dbString); - exit(mongoose, 999); - } else { - // get the list of collections - mongoose.connection.db.listCollections().toArray(function (err, collections) { - if (err) { - console.log('Error: Unable to list collections in database: %s', err); - exit(mongoose, 1); - } else { - // check if there are any collections - if (collections.length > 0) { - var counter = 0; + mongoose.connect(dbString).then(() => { + // get the list of collections + mongoose.connection.db.listCollections().toArray().then((collections) => { + // check if there are any collections + if (collections.length > 0) { + var counter = 0; - // loop through all collections - collections.forEach((collection) => { - console.log(`Deleting ${collection.name}..`); + // loop through all collections + collections.forEach((collection) => { + console.log(`Deleting ${collection.name}..`); - // delete this collection - drop_collection(mongoose, collection.name, function(retVal) { - // check if the collection was successfully deleted - if (retVal) - counter++; + // delete this collection + drop_collection(mongoose, collection.name, function(retVal) { + // check if the collection was successfully deleted + if (retVal) + counter++; - // check if the last collection was deleted - if (counter == collections.length) { - // finish the delete process - console.log('Finished deleting database'); - exit(mongoose, 0); - } - }); - }); - } else { - // nothing to delete - console.log('Nothing to delete, the database is already empty..'); + // check if the last collection was deleted + if (counter == collections.length) { + // finish the delete process + console.log('Finished deleting database'); + exit(mongoose, 0); + } + }); + }); + } else { + // nothing to delete + console.log('Nothing to delete, the database is already empty..'); - // finish the delete process - exit(mongoose, 0); - } - } - }); - } + // finish the delete process + exit(mongoose, 0); + } + }).catch((err) => { + console.log('Error: Unable to list collections in database: %s', err); + exit(mongoose, 1); + }); + }).catch((err) => { + console.log('Error: Unable to connect to database: %s', err); + exit(mongoose, 999); }); } else { // another script process is currently running diff --git a/scripts/restore_backup.js b/scripts/restore_backup.js index d86ccc3..afca2e0 100644 --- a/scripts/restore_backup.js +++ b/scripts/restore_backup.js @@ -68,12 +68,15 @@ function check_module_directory_exists(dirName, cb) { function drop_collection(mongoose, colName, cb) { // attempt to delete the collection - mongoose.connection.db.dropCollection(colName, function(err, result) { - if (err || !result) { + mongoose.connection.db.dropCollection(colName).then((result) => { + if (!result) { console.log(`Error: Unable to delete the ${colName} collection`); exit(mongoose, 1); } else return cb(true); + }).catch((err) => { + console.log(err); + exit(mongoose, 1); }); } @@ -85,45 +88,41 @@ function delete_database(mongoose, settings, cb) { mongoose.set('strictQuery', true); // connect to mongo database - mongoose.connect(dbString, function(err) { - if (err) { - console.log('Error: Unable to connect to database: %s', dbString); - exit(mongoose, 999); - } else { - // get the list of collections - mongoose.connection.db.listCollections().toArray(function (err, collections) { - if (err) { - console.log('Error: Unable to list collections in database: %s', err); - exit(mongoose, 1); - } else { - // check if there are any collections - if (collections.length > 0) { - var counter = 0; + mongoose.connect(dbString).then(() => { + // get the list of collections + mongoose.connection.db.listCollections().toArray().then((collections) => { + // check if there are any collections + if (collections.length > 0) { + var counter = 0; - // loop through all collections - collections.forEach((collection) => { - console.log(`Deleting ${collection.name}..`); + // loop through all collections + collections.forEach((collection) => { + console.log(`Deleting ${collection.name}..`); - // delete this collection - drop_collection(mongoose, collection.name, function(retVal) { - // check if the collection was successfully deleted - if (retVal) - counter++; + // delete this collection + drop_collection(mongoose, collection.name, function(retVal) { + // check if the collection was successfully deleted + if (retVal) + counter++; - // check if the last collection was deleted - if (counter == collections.length) { - // finished the delete process - return cb(true); - } - }); - }); - } else { - // nothing to delete - return cb(true); - } - } - }); - } + // check if the last collection was deleted + if (counter == collections.length) { + // finished the delete process + return cb(true); + } + }); + }); + } else { + // nothing to delete + return cb(true); + } + }).catch((err) => { + console.log(err); + return cb(true); + }); + }).catch((err) => { + console.log('Error: Unable to connect to database: %s', err); + exit(mongoose, 999); }); } diff --git a/scripts/sync.js b/scripts/sync.js index f01631a..6c45621 100644 --- a/scripts/sync.js +++ b/scripts/sync.js @@ -89,7 +89,7 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) { Stats.updateOne({coin: coin}, { last: block_height - 1, txes: txes - }, function() {}); + }).then(() => {}); } else if (check_only == 1) { console.log('Checking block ' + block_height + '...'); } @@ -99,7 +99,7 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) { lib.get_block(blockhash, function(block) { if (block) { async.eachLimit(block.tx, task_limit_txs, function(txid, next_tx) { - Tx.findOne({txid: txid}, function(err, tx) { + Tx.findOne({txid: txid}).then((tx) => { if (tx && check_only != 2) { setTimeout(function() { tx = null; @@ -155,6 +155,19 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) { } }); } + }).catch((err) => { + console.log(err); + + setTimeout(function() { + tx = null; + + // check if the script is stopping + if (stopSync && check_only != 2) { + // stop the loop + next_tx({}); + } else + next_tx(); + }, timeout); }); }, function() { setTimeout(function() { @@ -209,7 +222,10 @@ function update_tx_db(coin, start, end, txes, timeout, check_only, cb) { } // update local stats - Stats.updateOne({coin: coin}, statUpdateObject, function() { + Stats.updateOne({coin: coin}, statUpdateObject).then(() => { + return cb(txes); + }).catch((err) => { + console.log(err); return cb(txes); }); }); @@ -246,7 +262,9 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, Stats.updateOne({coin: settings.coin.name}, { orphan_index: current_block - 1, orphan_current: (unresolved_forks.length == 0 ? 0 : unresolved_forks[0]) - }, function() {}); + }).then(() => {}).catch((staterr) => { + console.log(staterr); + }); } // do not show the 'checking...' msg if this block is about to be resolved @@ -360,7 +378,7 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, }); }, function() { // get the most recent stats - Stats.findOne({coin: settings.coin.name}, function(stat_err, stats) { + Stats.findOne({coin: settings.coin.name}).then((stats) => { // add missing txes for the current block update_tx_db(settings.coin.name, current_block, current_block, (stats.txes + tx_count), timeout, 2, function(updated_tx_count) { // update the stats collection by removing the orphaned txes in this block from the tx count @@ -368,9 +386,19 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, Stats.updateOne({coin: settings.coin.name}, { orphan_index: current_block, orphan_current: (unresolved_forks.length == 0 ? 0 : unresolved_forks[0]) - }, function (stats_err) { - if (stats_err != null) - console.log(stats_err); + }).then(() => { + // clear the saved block hash data + correct_block_data = null; + + // move to the next block + current_block++; + + setTimeout(function() { + // process next block + next(null); + }, timeout); + }).catch((err) => { + console.log(err); // clear the saved block hash data correct_block_data = null; @@ -384,6 +412,13 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, }, timeout); }); }); + }).catch((err) => { + console.log(err); + + setTimeout(function() { + // process next block + next(null); + }, timeout); }); }); }); @@ -420,7 +455,7 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, console.log('Finished looking for forks'); // get the list of orphans with a null next_blockhash - Orphans.find({next_blockhash: null}).exec(function(next_err, orphans) { + Orphans.find({next_blockhash: null}).exec().then((orphans) => { // loop through the list of orphans lib.syncLoop(orphans.length, function(orphan_loop) { var o = orphan_loop.iteration(); @@ -432,7 +467,14 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, // update the next blockhash for this orphan record Orphans.updateOne({blockindex: orphans[o].blockindex, orphan_blockhash: orphans[o].orphan_blockhash}, { next_blockhash: good_block_data.nextblockhash - }, function() { + }).then(() => { + setTimeout(function() { + // move to the next orphan record + orphan_loop.next(); + }, timeout); + }).catch((err) => { + console.log(err); + setTimeout(function() { // move to the next orphan record orphan_loop.next(); @@ -450,11 +492,17 @@ function update_orphans(orphan_index, orphan_current, last_blockindex, timeout, Stats.updateOne({coin: settings.coin.name}, { orphan_index: current_block - 1, orphan_current: (unresolved_forks.length == 0 ? 0 : unresolved_forks[0]) - }, function() { + }).then(() => { // finished fixing orphaned block data return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); }); + }).catch((err) => { + console.log(err); + return cb(); }); } }); @@ -485,10 +533,8 @@ function get_earliest_orphan_block(orphan_index, orphan_current, last_blockindex { $project: { "_id": 1 }} - ], function(err, data) { - if (err) { - return cb(null, err); - } else if (data.length > 0) { + ]).option({ allowDiskUse: true }).then((data) => { + if (data.length > 0) { // found the first unprocessed orphaned block orphan_current = data[0]._id; orphan_index = (orphan_current - 1); @@ -497,7 +543,7 @@ function get_earliest_orphan_block(orphan_index, orphan_current, last_blockindex Stats.updateOne({coin: settings.coin.name}, { orphan_current: orphan_current, orphan_index: orphan_index - }, function() { + }).then(() => { return cb({orphan_index: orphan_index, orphan_current: orphan_current}, null); }); } else { @@ -509,11 +555,13 @@ function get_earliest_orphan_block(orphan_index, orphan_current, last_blockindex Stats.updateOne({coin: settings.coin.name}, { orphan_current: orphan_current, orphan_index: orphan_index - }, function() { + }).then(() => { return cb({orphan_index: orphan_index, orphan_current: orphan_current}, null); }); } - }).option({ allowDiskUse: true }); + }).catch((err) => { + return cb(null, err); + }); } else return cb({orphan_index: orphan_index, orphan_current: orphan_current}, null); } @@ -531,11 +579,8 @@ function check_block_height_for_fork(block_height, cb) { _id: "$blockindex", blockhashes: { $addToSet: "$blockhash" } }} - ], function(err, data) { - if (err) { - // an error was returned - return cb(null, err); - } else if (data.length > 0) { + ]).then((data) => { + if (data.length > 0) { // lookup the "good" block hash using the block height lib.get_blockhash(block_height, function(block_hash) { // check if there is more than 1 block hash @@ -568,6 +613,9 @@ function check_block_height_for_fork(block_height, cb) { // no blocks found return cb(null, null); } + }).catch((err) => { + // an error was returned + return cb(null, err); }); } @@ -581,27 +629,22 @@ function create_orphan(blockindex, orphan_blockhash, good_blockhash, prev_blockh }); // create a new orphan record in the local database - newOrphan.save(function(err) { - if (err) { - // check if this is a duplicate key error which can be ignored - if (!(err.toString().indexOf('E11000') > -1 || err.toString().indexOf('duplicate key error') > -1)) - console.log(err); + newOrphan.save().then(() => { + // new orphan record saved successfully + return cb(); + }).catch((err) => { + // check if this is a duplicate key error which can be ignored + if (!(err.toString().indexOf('E11000') > -1 || err.toString().indexOf('duplicate key error') > -1)) + console.log(err); - return cb(); - } else { - // new orphan record saved successfully - return cb(); - } + return cb(); }); } function get_orphaned_txids(block_hash, cb) { // get all transactions by block hash - Tx.find({blockhash: block_hash}).exec(function(err, txes) { - if (err) { - // an error was returned - return cb(null, err); - } else if (txes.length > 0) { + Tx.find({blockhash: block_hash}).exec().then((txes) => { + if (txes.length > 0) { // found at least one orphaned transaction var txids = []; @@ -614,6 +657,9 @@ function get_orphaned_txids(block_hash, cb) { // no txes found return cb(null, null); } + }).catch((err) => { + // an error was returned + return cb(null, err); }); } @@ -656,11 +702,8 @@ function check_add_tx(txid, blockhash, tx_count, cb) { function delete_and_cleanup_tx(txid, block_height, tx_count, timeout, cb) { // lookup all address tx records associated with the current tx - AddressTx.find({txid: txid}).exec(function (find_address_err, address_txes) { - if (find_address_err != null) { - console.log(find_address_err); - return cb(tx_count); - } else if (address_txes.length == 0) { + AddressTx.find({txid: txid}).exec().then((address_txes) => { + if (address_txes.length == 0) { // no vouts for this tx, so just delete the tx without cleaning up addresses delete_tx(txid, block_height, function(tx_err, tx_result) { if (tx_err) { @@ -673,195 +716,211 @@ function delete_and_cleanup_tx(txid, block_height, tx_count, timeout, cb) { }); } else { // lookup the current tx in the local database - Tx.findOne({txid: txid}, function(find_tx_err, tx) { - if (find_tx_err != null) { - console.log(find_tx_err); - return cb(tx_count); - } else { - var addressTxArray = []; - var has_vouts = (tx.vout != null && tx.vout.length > 0); + Tx.findOne({txid: txid}).then((tx) => { + var addressTxArray = []; + var has_vouts = (tx.vout != null && tx.vout.length > 0); - // check if this is a coinbase tx - if (tx.vin == null || tx.vin.length == 0) { - // add a coinbase tx into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: 'coinbase', - amount: tx.total - }); - } - - // check if there are any vin addresses - if (tx.vin != null && tx.vin.length > 0) { - // loop through the vin data - for (var vin_tx_counter = tx.vin.length - 1; vin_tx_counter >= 0; vin_tx_counter--) { - // loop through the addresstxe data - for (var vin_addresstx_counter = address_txes.length - 1; vin_addresstx_counter >= 0; vin_addresstx_counter--) { - // check if there is a tx record that exactly matches to the addresstx - if (tx.vin[vin_tx_counter].addresses == address_txes[vin_addresstx_counter].a_id && tx.vin[vin_tx_counter].amount == -address_txes[vin_addresstx_counter].amount) { - // add the address into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: tx.vin[vin_tx_counter].addresses, - amount: address_txes[vin_addresstx_counter].amount - }); - - // remove the found records from both arrays - tx.vin.splice(vin_tx_counter, 1); - address_txes.splice(vin_addresstx_counter, 1); - - break; - } - } - } - } - - // check if there are any vout addresses - if (tx.vout != null && tx.vout.length > 0) { - // loop through the vout data - for (var vout_tx_counter = tx.vout.length - 1; vout_tx_counter >= 0; vout_tx_counter--) { - // loop through the addresstxe data - for (var vout_addresstx_counter = address_txes.length - 1; vout_addresstx_counter >= 0; vout_addresstx_counter--) { - // check if there is a tx record that exactly matches to the addresstx - if (tx.vout[vout_tx_counter].addresses == address_txes[vout_addresstx_counter].a_id && tx.vout[vout_tx_counter].amount == address_txes[vout_addresstx_counter].amount) { - // add the address into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: tx.vout[vout_tx_counter].addresses, - amount: address_txes[vout_addresstx_counter].amount - }); - - // remove the found records from both arrays - tx.vout.splice(vout_tx_counter, 1); - address_txes.splice(vout_addresstx_counter, 1); - - break; - } - } - } - } - - // check if there are still more vin/vout records to process - if (tx.vin.length > 0 || tx.vout.length > 0 || address_txes.length > 0) { - // get all unique remaining addresses - var address_list = []; - - // get unique addresses from the tx vin - tx.vin.forEach(function(vin) { - if (address_list.indexOf(vin.addresses) == -1) - address_list.push(vin.addresses); - }); - - // get unique addresses from the tx vout - tx.vout.forEach(function(vout) { - if (address_list.indexOf(vout.addresses) == -1) - address_list.push(vout.addresses); - }); - - // get unique addresses from the addresstxes - address_txes.forEach(function(address_tx) { - if (address_list.indexOf(address_tx.a_id) == -1) - address_list.push(address_tx.a_id); - }); - - // loop through each unique address - address_list.forEach(function(address) { - var vin_total = 0; - var vout_total = 0; - var address_tx_total = 0; - - // add up all the vin amounts for this address - tx.vin.forEach(function(vin) { - // check if this is the correct address - if (vin.addresses == address) - vin_total += vin.amount; - }); - - // add up all the vout amounts for this address - tx.vout.forEach(function(vout) { - // check if this is the correct address - if (vout.addresses == address) - vout_total += vout.amount; - }); - - // add up all the addresstx amounts for this address - address_txes.forEach(function(address_tx) { - // check if this is the correct address - if (address_tx.a_id == address) - address_tx_total += address_tx.amount; - }); - - // check if the tx and addresstx totals match - if ((vout_total - vin_total) == address_tx_total) { - // the values match (this indicates that this address sent coins to themselves) - // add a vin record for this address into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: address, - amount: -vin_total - }); - - // add a vout record for this address into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: address, - amount: vout_total - }); - } else { - // the values do not match (this indicates there was a problem saving the data) - // output the data for this address as-is, using the addresstx values - address_txes.forEach(function(address_tx) { - // check if this is the correct address - if (address_tx.a_id == address) { - // add a record for this address into the addressTxArray array - addressTxArray.push({ - txid: txid, - a_id: address, - amount: address_tx.amount - }); - } - }); - } - }); - } - - // loop through the address txes - lib.syncLoop(addressTxArray.length, function(address_loop) { - var a = address_loop.iteration(); - - // fix the balance, sent and received data for the current address - fix_address_data(addressTxArray[a], function() { - setTimeout(function() { - // move to the next address record - address_loop.next(); - }, timeout); - }); - }, function() { - // delete all AddressTx records from the local collection for this tx - AddressTx.deleteMany({txid: txid}, function(address_tx_err, address_tx_result) { - if (address_tx_err) - console.log(address_tx_err); - - // delete the tx from the local database - delete_tx(txid, block_height, function(tx_err, tx_result) { - if (tx_err) { - console.log(tx_err); - return cb(tx_count); - } else { - // check if the deleted tx had vouts - if (has_vouts) { - // keep a running total of txes that were removed - tx_count -= tx_result.deletedCount; - } - - return cb(tx_count); - } - }); - }); + // check if this is a coinbase tx + if (tx.vin == null || tx.vin.length == 0) { + // add a coinbase tx into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: 'coinbase', + amount: tx.total }); } + + // check if there are any vin addresses + if (tx.vin != null && tx.vin.length > 0) { + // loop through the vin data + for (var vin_tx_counter = tx.vin.length - 1; vin_tx_counter >= 0; vin_tx_counter--) { + // loop through the addresstxe data + for (var vin_addresstx_counter = address_txes.length - 1; vin_addresstx_counter >= 0; vin_addresstx_counter--) { + // check if there is a tx record that exactly matches to the addresstx + if (tx.vin[vin_tx_counter].addresses == address_txes[vin_addresstx_counter].a_id && tx.vin[vin_tx_counter].amount == -address_txes[vin_addresstx_counter].amount) { + // add the address into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: tx.vin[vin_tx_counter].addresses, + amount: address_txes[vin_addresstx_counter].amount + }); + + // remove the found records from both arrays + tx.vin.splice(vin_tx_counter, 1); + address_txes.splice(vin_addresstx_counter, 1); + + break; + } + } + } + } + + // check if there are any vout addresses + if (tx.vout != null && tx.vout.length > 0) { + // loop through the vout data + for (var vout_tx_counter = tx.vout.length - 1; vout_tx_counter >= 0; vout_tx_counter--) { + // loop through the addresstxe data + for (var vout_addresstx_counter = address_txes.length - 1; vout_addresstx_counter >= 0; vout_addresstx_counter--) { + // check if there is a tx record that exactly matches to the addresstx + if (tx.vout[vout_tx_counter].addresses == address_txes[vout_addresstx_counter].a_id && tx.vout[vout_tx_counter].amount == address_txes[vout_addresstx_counter].amount) { + // add the address into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: tx.vout[vout_tx_counter].addresses, + amount: address_txes[vout_addresstx_counter].amount + }); + + // remove the found records from both arrays + tx.vout.splice(vout_tx_counter, 1); + address_txes.splice(vout_addresstx_counter, 1); + + break; + } + } + } + } + + // check if there are still more vin/vout records to process + if (tx.vin.length > 0 || tx.vout.length > 0 || address_txes.length > 0) { + // get all unique remaining addresses + var address_list = []; + + // get unique addresses from the tx vin + tx.vin.forEach(function(vin) { + if (address_list.indexOf(vin.addresses) == -1) + address_list.push(vin.addresses); + }); + + // get unique addresses from the tx vout + tx.vout.forEach(function(vout) { + if (address_list.indexOf(vout.addresses) == -1) + address_list.push(vout.addresses); + }); + + // get unique addresses from the addresstxes + address_txes.forEach(function(address_tx) { + if (address_list.indexOf(address_tx.a_id) == -1) + address_list.push(address_tx.a_id); + }); + + // loop through each unique address + address_list.forEach(function(address) { + var vin_total = 0; + var vout_total = 0; + var address_tx_total = 0; + + // add up all the vin amounts for this address + tx.vin.forEach(function(vin) { + // check if this is the correct address + if (vin.addresses == address) + vin_total += vin.amount; + }); + + // add up all the vout amounts for this address + tx.vout.forEach(function(vout) { + // check if this is the correct address + if (vout.addresses == address) + vout_total += vout.amount; + }); + + // add up all the addresstx amounts for this address + address_txes.forEach(function(address_tx) { + // check if this is the correct address + if (address_tx.a_id == address) + address_tx_total += address_tx.amount; + }); + + // check if the tx and addresstx totals match + if ((vout_total - vin_total) == address_tx_total) { + // the values match (this indicates that this address sent coins to themselves) + // add a vin record for this address into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: address, + amount: -vin_total + }); + + // add a vout record for this address into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: address, + amount: vout_total + }); + } else { + // the values do not match (this indicates there was a problem saving the data) + // output the data for this address as-is, using the addresstx values + address_txes.forEach(function(address_tx) { + // check if this is the correct address + if (address_tx.a_id == address) { + // add a record for this address into the addressTxArray array + addressTxArray.push({ + txid: txid, + a_id: address, + amount: address_tx.amount + }); + } + }); + } + }); + } + + // loop through the address txes + lib.syncLoop(addressTxArray.length, function(address_loop) { + var a = address_loop.iteration(); + + // fix the balance, sent and received data for the current address + fix_address_data(addressTxArray[a], function() { + setTimeout(function() { + // move to the next address record + address_loop.next(); + }, timeout); + }); + }, function() { + // delete all AddressTx records from the local collection for this tx + AddressTx.deleteMany({txid: txid}).then((address_tx_result) => { + // delete the tx from the local database + delete_tx(txid, block_height, function(tx_err, tx_result) { + if (tx_err) { + console.log(tx_err); + return cb(tx_count); + } else { + // check if the deleted tx had vouts + if (has_vouts) { + // keep a running total of txes that were removed + tx_count -= tx_result.deletedCount; + } + + return cb(tx_count); + } + }); + }).catch((err) => { + console.log(err); + + // delete the tx from the local database + delete_tx(txid, block_height, function(tx_err, tx_result) { + if (tx_err) { + console.log(tx_err); + return cb(tx_count); + } else { + // check if the deleted tx had vouts + if (has_vouts) { + // keep a running total of txes that were removed + tx_count -= tx_result.deletedCount; + } + + return cb(tx_count); + } + }); + }); + }); + }).catch((err) => { + console.log(err); + return cb(tx_count); }); } + }).catch((err) => { + console.log(err); + return cb(tx_count); }); } @@ -887,19 +946,21 @@ function fix_address_data(address_data, cb) { $inc: addr_inc }, { upsert: false - }, function (address_err, return_address) { - if (address_err != null) - console.log(address_err); - + }).then((return_address) => { // finished fixing the address balance data return cb(); + }).catch((err) => { + console.log(err); + return cb(); }); } function delete_tx(txid, block_height, cb) { // delete the tx from the local database - Tx.deleteOne({txid: txid, blockindex: block_height}, function(tx_err, tx_result) { - return cb(tx_err, tx_result); + Tx.deleteOne({txid: txid, blockindex: block_height}).then((tx_result) => { + return cb(null, tx_result); + }).catch((err) => { + return cb(err, null); }); } @@ -1094,11 +1155,8 @@ if (lib.is_locked([database]) == false) { mongoose.set('strictQuery', true); - mongoose.connect(dbString, function(err) { - if (err) { - console.log('Error: Unable to connect to database: %s', dbString); - exit(1); - } else if (database == 'index') { + mongoose.connect(dbString).then(() => { + if (database == 'index') { db.check_stats(settings.coin.name, function(exists) { if (exists == false) { console.log('Run \'npm start\' to create database structures before running this script.'); @@ -1110,22 +1168,22 @@ if (lib.is_locked([database]) == false) { // determine which index mode to run if (mode == 'reindex') { console.log('Deleting transactions.. Please wait..'); - Tx.deleteMany({}, function(err) { + Tx.deleteMany({}).then(() => { console.log('Transactions deleted successfully'); console.log('Deleting addresses.. Please wait..'); - Address.deleteMany({}, function(err2) { + Address.deleteMany({}).then(() => { console.log('Addresses deleted successfully'); console.log('Deleting address transactions.. Please wait..'); - AddressTx.deleteMany({}, function(err3) { + AddressTx.deleteMany({}).then(() => { console.log('Address transactions deleted successfully'); console.log('Deleting top 100 data.. Please wait..'); Richlist.updateOne({coin: settings.coin.name}, { received: [], balance: [] - }, function(err3) { + }).then(() => { console.log('Top 100 data deleted successfully'); console.log('Deleting block index.. Please wait..'); @@ -1137,7 +1195,7 @@ if (lib.is_locked([database]) == false) { richlist_last_updated: 0, orphan_index: 0, orphan_current: 0 - }, function() { + }).then(() => { console.log('Block index deleted successfully'); // Check if the sync msg should be shown @@ -1184,10 +1242,25 @@ if (lib.is_locked([database]) == false) { }); } }); + }).catch((err) => { + console.log(err); + exit(1); }); + }).catch((err) => { + console.log(err); + exit(1); }); + }).catch((err) => { + console.log(err); + exit(1); }); + }).catch((err) => { + console.log(err); + exit(1); }); + }).catch((err) => { + console.log(err); + exit(1); }); } else if (mode == 'check') { console.log('Checking blocks.. Please wait..'); @@ -1284,40 +1357,55 @@ if (lib.is_locked([database]) == false) { console.log('Calculating tx count.. Please wait..'); // Resetting the transaction counter requires a single lookup on the txes collection to find all txes that have a positive or zero total and 1 or more vout - Tx.find({'total': {$gte: 0}, 'vout': { $gte: { $size: 1 }}}).countDocuments(function(err, count) { + Tx.find({'total': {$gte: 0}, 'vout': { $gte: { $size: 1 }}}).countDocuments().then((count) => { console.log('Found tx count: ' + count.toString()); Stats.updateOne({coin: settings.coin.name}, { txes: count - }, function() { + }).then(() => { console.log('Tx count update complete'); exit(0); + }).catch((err) => { + console.log(err); + exit(1); }); + }).catch((err) => { + console.log(err); + exit(1); }); } else if (mode == 'reindex-last') { console.log('Finding last blockindex.. Please wait..'); // Resetting the last blockindex counter requires a single lookup on the txes collection to find the last indexed blockindex - Tx.find({}, {blockindex:1, _id:0}).sort({blockindex: -1}).limit(1).exec(function(err, tx) { + Tx.find({}, {blockindex:1, _id:0}).sort({blockindex: -1}).limit(1).exec().then((tx) => { // check if any blocks exists - if (err != null || tx == null || tx.length == 0) { + if (tx == null || tx.length == 0) { console.log('No blocks found. setting last blockindex to 0.'); Stats.updateOne({coin: settings.coin.name}, { last: 0 - }, function() { + }).then(() => { console.log('Last blockindex update complete'); exit(0); + }).catch((err) => { + console.log(err); + exit(1); }); } else { console.log('Found last blockindex: ' + tx[0].blockindex.toString()); Stats.updateOne({coin: settings.coin.name}, { last: tx[0].blockindex - }, function() { + }).then(() => { console.log('Last blockindex update complete'); exit(0); + }).catch((err) => { + console.log(err); + exit(1); }); } + }).catch((err) => { + console.log(err); + exit(1); }); } } else { @@ -1578,6 +1666,9 @@ if (lib.is_locked([database]) == false) { exit(1); } } + }).catch((err) => { + console.log('Error: Unable to connect to database: %s', err); + exit(1); }); } else { // another script process is currently running