2021-03-17 17:54:09 -06:00
var mongoose = require ( 'mongoose' ) ,
Stats = require ( '../models/stats' ) ,
Markets = require ( '../models/markets' ) ,
Masternode = require ( '../models/masternode' ) ,
Address = require ( '../models/address' ) ,
AddressTx = require ( '../models/addresstx' ) ,
Tx = require ( '../models/tx' ) ,
Richlist = require ( '../models/richlist' ) ,
Peers = require ( '../models/peers' ) ,
Heavy = require ( '../models/heavy' ) ,
lib = require ( './explorer' ) ,
settings = require ( './settings' ) ,
2021-03-20 01:34:13 -06:00
locale = require ( './locale' ) ,
2021-03-17 17:54:09 -06:00
fs = require ( 'fs' ) ,
coindesk = require ( './apis/coindesk' ) ,
async = require ( 'async' ) ;
2019-05-27 10:33:22 -07:00
2019-10-17 21:51:13 -06:00
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 ) {
if ( address )
return cb ( address ) ;
else
return cb ( ) ;
} ) ;
} else {
// slower search but matches exact string ignoring case
Address . findOne ( { a _id : { $regex : '^' + hash + '$' , $options : 'i' } } , function ( err , address ) {
if ( address )
return cb ( address ) ;
else
return cb ( ) ;
} ) ;
}
2019-05-27 10:33:22 -07:00
}
2020-11-20 16:28:28 -07:00
function find _address _tx ( address , hash , cb ) {
AddressTx . findOne ( { a _id : address , txid : hash } , function ( err , address _tx ) {
2021-03-17 17:54:09 -06:00
if ( address _tx )
2020-11-20 16:28:28 -07:00
return cb ( address _tx ) ;
2021-03-17 17:54:09 -06:00
else
2020-11-20 16:28:28 -07:00
return cb ( ) ;
} ) ;
}
2019-05-27 10:33:22 -07:00
function find _richlist ( coin , cb ) {
Richlist . findOne ( { coin : coin } , function ( err , richlist ) {
2021-03-17 17:54:09 -06:00
if ( richlist )
2019-05-27 10:33:22 -07:00
return cb ( richlist ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( ) ;
} ) ;
}
2020-11-22 15:00:47 -07:00
function update _address ( hash , blockheight , txid , amount , type , cb ) {
var to _sent = false ;
var to _received = false ;
var addr _inc = { }
2021-03-17 17:54:09 -06:00
if ( hash == 'coinbase' )
2020-11-22 15:00:47 -07:00
addr _inc . sent = amount ;
2021-03-17 17:54:09 -06:00
else {
2020-11-22 15:00:47 -07:00
if ( type == 'vin' ) {
addr _inc . sent = amount ;
addr _inc . balance = - amount ;
2019-05-27 10:33:22 -07:00
} else {
2020-11-22 15:00:47 -07:00
addr _inc . received = amount ;
addr _inc . balance = amount ;
}
}
2021-03-17 17:54:09 -06:00
2020-11-22 15:00:47 -07:00
Address . findOneAndUpdate ( { a _id : hash } , {
$inc : addr _inc
} , {
new : true ,
upsert : true
} , function ( err , address ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-11-22 15:00:47 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else {
if ( hash != 'coinbase' ) {
2020-11-22 17:35:57 -07:00
AddressTx . findOneAndUpdate ( { a _id : hash , txid : txid } , {
2020-11-22 18:27:04 -07:00
$inc : {
amount : addr _inc . balance
} ,
2020-11-22 17:35:57 -07:00
$set : {
a _id : hash ,
blockindex : blockheight ,
2020-11-22 18:27:04 -07:00
txid : txid
2020-11-22 17:35:57 -07:00
}
} , {
new : true ,
upsert : true
} , function ( err , addresstx ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-11-22 17:35:57 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else
2020-11-22 17:35:57 -07:00
return cb ( ) ;
} ) ;
2021-03-17 17:54:09 -06:00
} else
2020-11-22 17:35:57 -07:00
return cb ( ) ;
2019-05-27 10:33:22 -07:00
}
} ) ;
}
function find _tx ( txid , cb ) {
Tx . findOne ( { txid : txid } , function ( err , tx ) {
2021-03-17 17:54:09 -06:00
if ( tx )
2019-05-27 10:33:22 -07:00
return cb ( tx ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
} ) ;
}
2020-11-20 18:56:25 -07:00
function save _tx ( txid , blockheight , cb ) {
2021-01-22 15:04:32 -07:00
lib . get _rawtransaction ( txid , function ( tx ) {
2020-12-07 21:32:43 -07:00
if ( tx && tx != 'There was an error. Check your console.' ) {
2021-03-20 01:34:13 -06:00
lib . prepare _vin ( tx , function ( vin , tx _type _vin ) {
lib . prepare _vout ( tx . vout , txid , vin , ( ( ! settings . blockchain _specific . zksnarks . enabled || typeof tx . vjoinsplit === 'undefined' || tx . vjoinsplit == null ) ? [ ] : tx . vjoinsplit ) , function ( vout , nvin , tx _type _vout ) {
2020-11-20 18:56:25 -07:00
lib . syncLoop ( vin . length , function ( loop ) {
var i = loop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
update _address ( nvin [ i ] . addresses , blockheight , txid , nvin [ i ] . amount , 'vin' , function ( ) {
2020-11-20 18:56:25 -07:00
loop . next ( ) ;
} ) ;
2021-01-22 15:04:32 -07:00
} , function ( ) {
2020-11-20 18:56:25 -07:00
lib . syncLoop ( vout . length , function ( subloop ) {
var t = subloop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
2020-11-20 18:56:25 -07:00
if ( vout [ t ] . addresses ) {
2021-01-22 15:04:32 -07:00
update _address ( vout [ t ] . addresses , blockheight , txid , vout [ t ] . amount , 'vout' , function ( ) {
2020-11-20 18:56:25 -07:00
subloop . next ( ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-22 15:04:32 -07:00
} else
2020-11-20 18:56:25 -07:00
subloop . next ( ) ;
2021-01-22 15:04:32 -07:00
} , function ( ) {
lib . calculate _total ( vout , function ( total ) {
2020-11-20 18:56:25 -07:00
var newTx = new Tx ( {
txid : tx . txid ,
vin : nvin ,
vout : vout ,
total : total . toFixed ( 8 ) ,
timestamp : tx . time ,
blockhash : tx . blockhash ,
2021-03-20 01:34:13 -06:00
blockindex : blockheight ,
tx _type : ( tx _type _vout == null ? tx _type _vin : tx _type _vout )
2020-11-20 18:56:25 -07:00
} ) ;
2021-03-17 17:54:09 -06:00
2020-11-20 18:56:25 -07:00
newTx . save ( function ( err ) {
2021-01-22 15:04:32 -07:00
if ( err )
2020-12-03 14:16:34 -07:00
return cb ( err , false ) ;
2021-01-22 15:04:32 -07:00
else
2020-12-03 14:16:34 -07:00
return cb ( null , vout . length > 0 ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
} ) ;
} ) ;
2020-11-20 18:56:25 -07:00
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-22 15:04:32 -07:00
} else
2020-12-03 14:16:34 -07:00
return cb ( 'tx not found: ' + txid , false ) ;
2019-05-27 10:33:22 -07:00
} ) ;
}
2021-01-22 15:04:32 -07:00
function get _market _data ( market , coin _symbol , pair _symbol , cb ) {
2020-11-27 20:34:15 -07:00
if ( fs . existsSync ( './lib/markets/' + market + '.js' ) ) {
2020-11-23 17:19:42 -07:00
exMarket = require ( './markets/' + market ) ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
exMarket . get _data ( { coin : coin _symbol , exchange : pair _symbol } , function ( err , obj ) {
2020-11-23 17:19:42 -07:00
return cb ( err , obj ) ;
} ) ;
2021-01-22 15:04:32 -07:00
} else
2020-11-23 17:19:42 -07:00
return cb ( null ) ;
2020-11-20 16:28:28 -07:00
}
2021-03-20 01:34:13 -06:00
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 ) {
// check if field exists
if ( model _data ) {
// add field to all documents in the collection
model _obj . updateMany ( { } , {
$set : { [ field _name ] : default _value }
} , function ( ) {
return cb ( true ) ;
} ) ;
} else
return cb ( false ) ;
} ) ;
}
2019-05-27 10:33:22 -07:00
module . exports = {
// initialize DB
connect : function ( database , cb ) {
2020-11-22 17:39:46 -07:00
mongoose . connect ( database , { useNewUrlParser : true , useCreateIndex : true , useUnifiedTopology : true , useFindAndModify : false } , function ( err ) {
2019-05-27 10:33:22 -07:00
if ( err ) {
console . log ( 'Unable to connect to database: %s' , database ) ;
console . log ( 'Aborting' ) ;
process . exit ( 1 ) ;
}
2021-01-22 15:04:32 -07:00
return cb ( ) ;
2020-11-20 16:28:28 -07:00
} ) ;
} ,
2020-12-05 12:39:36 -07:00
check _show _sync _message : function ( ) {
2020-12-05 18:21:21 -07:00
return fs . existsSync ( './tmp/show_sync_message.tmp' ) ;
2020-12-05 12:39:36 -07:00
} ,
2020-12-30 18:22:02 -07:00
update _label : function ( hash , claim _name , cb ) {
2020-12-23 18:40:10 -07:00
find _address ( hash , false , function ( address ) {
if ( address ) {
Address . updateOne ( { a _id : hash } , {
2020-12-30 18:22:02 -07:00
name : claim _name
2020-12-23 18:40:10 -07:00
} , function ( ) {
2020-12-30 18:22:02 -07:00
// update claim name in richlist
module . exports . update _richlist _claim _name ( hash , claim _name , function ( ) {
// update claim name in masternode list
module . exports . update _masternode _claim _name ( hash , claim _name , function ( ) {
2020-12-26 22:01:36 -07:00
return cb ( '' ) ;
2020-12-30 18:22:02 -07:00
} ) ;
2020-12-23 18:40:10 -07:00
} ) ;
2020-11-22 14:39:10 -07:00
} ) ;
2020-12-26 22:01:36 -07:00
} else {
// address is not valid or does not have any transactions
return cb ( 'no_address' ) ;
2020-11-22 14:39:10 -07:00
}
} ) ;
} ,
2020-12-30 18:22:02 -07:00
update _richlist _claim _name : function ( hash , claim _name , cb ) {
// check if the richlist is enabled
2021-01-22 15:04:32 -07:00
if ( settings . richlist _page . enabled == true ) {
2020-12-30 18:22:02 -07:00
// ensure that if this address exists in the richlist that it displays the new alias
2021-01-22 15:04:32 -07:00
module . exports . get _richlist ( settings . coin . name , function ( richlist ) {
2020-12-30 18:22:02 -07:00
var updated = false ;
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// loop through received addresses
for ( r = 0 ; r < richlist . received . length ; r ++ ) {
// check if this is the correct address
if ( richlist . received [ r ] . a _id == hash ) {
// update the claim name
richlist . received [ r ] [ 'name' ] = claim _name ;
// mark as updated
updated = true ;
}
}
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// loop through balance addresses
for ( b = 0 ; b < richlist . balance . length ; b ++ ) {
// check if this is the correct address
if ( richlist . balance [ b ] . a _id == hash ) {
// update the claim name
richlist . balance [ b ] [ 'name' ] = claim _name ;
// mark as updated
2021-03-17 17:54:09 -06:00
updated = true ;
2020-12-30 18:22:02 -07:00
}
}
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// check if the address was updated in the richlist
if ( updated ) {
// save the richlist back to collection
2021-01-22 15:04:32 -07:00
Richlist . updateOne ( { coin : settings . coin . name } , {
2020-12-30 18:22:02 -07:00
received : richlist . received ,
balance : richlist . balance
} , function ( ) {
// finished updating the claim label
return cb ( '' ) ;
} ) ;
} else {
// finished updating the claim label
return cb ( '' ) ;
}
} ) ;
} else {
// richlist is not enabled so nothing to update
return cb ( '' ) ;
}
} ,
update _masternode _claim _name : function ( hash , claim _name , cb ) {
// check if the masternode list is enabled
2021-01-22 15:04:32 -07:00
if ( settings . masternodes _page . enabled == true ) {
2020-12-30 18:22:02 -07:00
// ensure that if this address exists in the masternode that it displays the new alias
module . exports . get _masternodes ( function ( masternodes ) {
var updated = false ;
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// loop through masternode addresses
for ( m = 0 ; m < masternodes . length ; m ++ ) {
// check if this is the correct address
if ( masternodes [ m ] . addr == hash ) {
// update the claim name
masternodes [ m ] [ 'claim_name' ] = claim _name ;
// mark as updated
updated = true ;
}
}
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// check if the address was updated in the masternode list
if ( updated ) {
// save the updated masternode back to collection
Masternode . updateOne ( { addr : hash } , {
claim _name : claim _name
} , function ( ) {
// finished updating the claim label
return cb ( '' ) ;
} ) ;
} else {
// finished updating the claim label
return cb ( '' ) ;
}
} ) ;
} else {
// masternode list is not enabled so nothing to update
return cb ( '' ) ;
}
} ,
2021-03-20 01:34:13 -06:00
check _txes : function ( cb ) {
Tx . findOne ( { } , function ( err , tx ) {
if ( tx ) {
// collection has data
// determine if tx_type field exists
check _add _db _field ( Tx , 'tx_type' , null , function ( exists ) {
return cb ( true ) ;
} ) ;
} else
return cb ( false ) ;
} ) ;
} ,
2019-05-27 10:33:22 -07:00
check _stats : function ( coin , cb ) {
Stats . findOne ( { coin : coin } , function ( err , stats ) {
2021-03-17 17:54:09 -06:00
if ( stats ) {
2021-03-20 01:34:13 -06:00
// collection has data
// determine if last_usd_price field exists
check _add _db _field ( Stats , 'last_usd_price' , 0 , function ( exists ) {
return cb ( true ) ;
2021-03-17 17:54:09 -06:00
} ) ;
} else
2019-05-27 10:33:22 -07:00
return cb ( false ) ;
} ) ;
} ,
get _stats : function ( coin , cb ) {
Stats . findOne ( { coin : coin } , function ( err , stats ) {
2021-03-17 17:54:09 -06:00
if ( stats )
2019-05-27 10:33:22 -07:00
return cb ( stats ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
} ) ;
} ,
create _stats : function ( coin , cb ) {
var newStats = new Stats ( {
coin : coin ,
2020-11-22 20:40:15 -07:00
last : 0
2019-05-27 10:33:22 -07:00
} ) ;
newStats . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
} else {
console . log ( "initial stats entry created for %s" , coin ) ;
return cb ( ) ;
}
} ) ;
} ,
2019-10-17 21:51:13 -06:00
get _address : function ( hash , caseSensitive , cb ) {
2021-03-17 17:54:09 -06:00
find _address ( hash , caseSensitive , function ( address ) {
2019-05-27 10:33:22 -07:00
return cb ( address ) ;
} ) ;
} ,
get _richlist : function ( coin , cb ) {
2021-03-17 17:54:09 -06:00
find _richlist ( coin , function ( richlist ) {
2019-05-27 10:33:22 -07:00
return cb ( richlist ) ;
} ) ;
} ,
2020-12-23 18:40:10 -07:00
// 'list' variable can be either 'received' or 'balance'
2021-01-22 15:04:32 -07:00
update _richlist : function ( list , cb ) {
// number of addresses to lookup
var total _addresses = 100 ;
// create the burn address array so that we omit burned coins from the rich list
var burn _addresses = settings . richlist _page . burned _coins . addresses ;
2021-03-17 17:54:09 -06:00
2019-10-18 22:31:07 -06:00
// always omit the private address from the richlist
2021-03-20 01:34:13 -06:00
burn _addresses . push ( 'hidden_address' ) ;
2019-10-18 22:31:07 -06:00
2020-12-23 18:40:10 -07:00
if ( list == 'received' ) {
2021-01-22 15:04:32 -07:00
// 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 ) {
Richlist . updateOne ( { coin : settings . coin . name } , {
2020-12-23 18:40:10 -07:00
received : addresses
2019-05-27 10:33:22 -07:00
} , function ( ) {
return cb ( ) ;
} ) ;
} ) ;
2020-12-23 18:40:10 -07:00
} else {
2021-01-22 15:04:32 -07:00
// 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 ) {
Richlist . updateOne ( { coin : settings . coin . name } , {
balance : addresses
} , function ( ) {
return cb ( ) ;
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-22 15:04:32 -07:00
} 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 ) {
var return _addresses = [ ] ;
var burned _balance = 0.0 ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
// loop through all richlist addresses
addresses . forEach ( function ( address ) {
// check if this is a burned coin address
if ( burn _addresses . findIndex ( p => p . toLowerCase ( ) == address . a _id . toLowerCase ( ) ) > - 1 ) {
// this is a burned coin address so save the balance, not the address
burned _balance += address . balance ;
} else if ( return _addresses . length < total _addresses ) {
// this is not a burned address so add it to the return list
return _addresses . push ( address ) ;
}
} ) ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
// update the rich list collection
Richlist . updateOne ( { coin : settings . coin . name } , {
balance : return _addresses ,
burned : burned _balance
} , function ( ) {
return cb ( ) ;
} ) ;
} ) ;
}
2019-05-27 10:33:22 -07:00
}
} ,
get _tx : function ( txid , cb ) {
2021-03-17 17:54:09 -06:00
find _tx ( txid , function ( tx ) {
2019-05-27 10:33:22 -07:00
return cb ( tx ) ;
} ) ;
} ,
get _txs : function ( block , cb ) {
var txs = [ ] ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
lib . syncLoop ( block . tx . length , function ( loop ) {
var i = loop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
find _tx ( block . tx [ i ] , function ( tx ) {
2019-05-27 10:33:22 -07:00
if ( tx ) {
txs . push ( tx ) ;
loop . next ( ) ;
2021-03-17 17:54:09 -06:00
} else
2019-05-27 10:33:22 -07:00
loop . next ( ) ;
2021-03-17 17:54:09 -06:00
} ) ;
} , function ( ) {
2019-05-27 10:33:22 -07:00
return cb ( txs ) ;
} ) ;
} ,
2021-01-01 18:24:39 -07:00
get _last _txs : function ( start , length , min , internal , cb ) {
2020-12-18 14:55:30 -07:00
this . get _last _txs _ajax ( start , length , min , function ( txs , count ) {
2020-11-28 20:40:37 -07:00
var data = [ ] ;
2021-01-01 18:24:39 -07:00
for ( i = 0 ; i < txs . length ; i ++ ) {
if ( internal ) {
var row = [ ] ;
2021-03-17 17:54:09 -06:00
2021-01-01 18:24:39 -07:00
row . push ( txs [ i ] . blockindex ) ;
row . push ( txs [ i ] . blockhash ) ;
row . push ( txs [ i ] . txid ) ;
row . push ( txs [ i ] . vout . length ) ;
row . push ( ( txs [ i ] . total / 100000000 ) ) ;
row . push ( txs [ i ] . timestamp ) ;
2021-03-17 17:54:09 -06:00
2021-01-01 18:24:39 -07:00
data . push ( row ) ;
} else {
data . push ( {
blockindex : txs [ i ] . blockindex ,
blockhash : txs [ i ] . blockhash ,
txid : txs [ i ] . txid ,
recipients : txs [ i ] . vout . length ,
amount : ( txs [ i ] . total / 100000000 ) ,
timestamp : txs [ i ] . timestamp
} ) ;
}
2020-11-28 20:40:37 -07:00
}
2021-03-17 17:54:09 -06:00
2020-12-17 23:55:57 -07:00
return cb ( data , count ) ;
2020-11-28 20:40:37 -07:00
} ) ;
} ,
2020-11-20 18:12:49 -07:00
get _last _txs _ajax : function ( start , length , min , cb ) {
2020-12-10 17:51:46 -07:00
// 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 ) {
2021-03-17 17:54:09 -06:00
// get last transactions where there is at least 1 vout
2020-12-10 17:51:46 -07:00
Tx . find ( { 'total' : { $gte : min } , 'vout' : { $gte : { $size : 1 } } } ) . sort ( { blockindex : - 1 } ) . skip ( Number ( start ) ) . limit ( Number ( length ) ) . exec ( function ( err , txs ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-12-10 17:51:46 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else
2020-12-10 17:51:46 -07:00
return cb ( txs , count ) ;
} ) ;
2020-11-23 15:35:14 -07:00
} ) ;
2020-12-10 17:51:46 -07:00
} 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)
2021-01-22 15:04:32 -07:00
Stats . findOne ( { coin : settings . coin . name } , function ( err , stats ) {
2020-12-10 17:51:46 -07:00
// 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 ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-12-10 17:51:46 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else
2020-12-10 17:51:46 -07:00
return cb ( txs , stats . txes ) ;
} ) ;
} ) ;
}
2020-11-20 17:32:06 -07:00
} ,
2020-11-19 21:37:42 -07:00
get _address _txs _ajax : function ( hash , start , length , cb ) {
var totalCount = 0 ;
2021-03-17 17:54:09 -06:00
AddressTx . find ( { a _id : hash } ) . countDocuments ( function ( err , count ) {
if ( err )
2020-11-19 21:37:42 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else {
2020-11-22 18:27:04 -07:00
totalCount = count ;
2021-03-17 17:54:09 -06:00
2020-11-22 18:27:04 -07:00
AddressTx . aggregate ( [
2020-11-23 20:58:34 -07:00
{ $match : { a _id : hash } } ,
2020-11-22 18:27:04 -07:00
{ $sort : { blockindex : - 1 } } ,
2020-11-23 20:58:34 -07:00
{ $skip : Number ( start ) } ,
2020-11-22 18:27:04 -07:00
{
$group : {
_id : '' ,
balance : { $sum : '$amount' }
}
} ,
{
$project : {
_id : 0 ,
balance : '$balance'
}
} ,
{ $sort : { blockindex : - 1 } }
] , function ( err , balance _sum ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-11-19 21:37:42 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else {
2020-11-23 15:35:14 -07:00
AddressTx . find ( { a _id : hash } ) . sort ( { blockindex : - 1 } ) . skip ( Number ( start ) ) . limit ( Number ( length ) ) . exec ( function ( err , address _tx ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-11-19 21:37:42 -07:00
return cb ( err ) ;
2021-03-17 17:54:09 -06:00
else {
2020-11-19 21:37:42 -07:00
var txs = [ ] ;
2020-11-22 18:27:04 -07:00
var count = address _tx . length ;
2020-11-23 20:58:34 -07:00
var running _balance = balance _sum . length > 0 ? balance _sum [ 0 ] . balance : 0 ;
2020-11-19 21:37:42 -07:00
var txs = [ ] ;
lib . syncLoop ( count , function ( loop ) {
var i = loop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
2020-11-23 20:58:34 -07:00
find _tx ( address _tx [ i ] . txid , function ( tx ) {
2020-11-20 16:28:28 -07:00
if ( tx && ! txs . includes ( tx ) ) {
2020-11-22 18:27:04 -07:00
tx . balance = running _balance ;
2020-11-19 21:37:42 -07:00
txs . push ( tx ) ;
loop . next ( ) ;
2020-11-20 16:28:28 -07:00
} else if ( ! txs . includes ( tx ) ) {
2020-11-19 21:37:42 -07:00
txs . push ( "1. Not found" ) ;
loop . next ( ) ;
2021-03-17 17:54:09 -06:00
} else
2020-11-20 16:28:28 -07:00
loop . next ( ) ;
2021-03-17 17:54:09 -06:00
2020-11-22 18:27:04 -07:00
running _balance = running _balance - address _tx [ i ] . amount ;
2021-03-17 17:54:09 -06:00
} ) ;
2020-11-19 21:37:42 -07:00
} , function ( ) {
return cb ( txs , totalCount ) ;
} ) ;
}
} ) ;
}
} ) ;
}
} ) ;
} ,
2021-01-22 15:04:32 -07:00
create _market : function ( coin _symbol , pair _symbol , market , cb ) {
2019-05-27 10:33:22 -07:00
var newMarkets = new Markets ( {
market : market ,
2021-01-22 15:04:32 -07:00
coin _symbol : coin _symbol ,
2021-03-17 17:54:09 -06:00
pair _symbol : pair _symbol
2019-05-27 10:33:22 -07:00
} ) ;
newMarkets . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
} else {
2021-01-22 15:04:32 -07:00
console . log ( "initial market entry created for %s: %s" , market , coin _symbol + '/' + pair _symbol ) ;
2019-05-27 10:33:22 -07:00
return cb ( ) ;
}
} ) ;
} ,
2021-01-22 15:04:32 -07:00
// 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 ) {
return cb ( market , exists ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ,
2021-01-22 15:04:32 -07:00
// 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 ) {
if ( data )
2019-05-27 10:33:22 -07:00
return cb ( data ) ;
2021-01-22 15:04:32 -07:00
else
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
} ) ;
} ,
// creates initial richlist entry in database; called on first launch of explorer
create _richlist : function ( coin , cb ) {
var newRichlist = new Richlist ( {
2021-03-17 17:54:09 -06:00
coin : coin
2019-05-27 10:33:22 -07:00
} ) ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
newRichlist . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
} else {
console . log ( "initial richlist entry created for %s" , coin ) ;
return cb ( ) ;
}
} ) ;
} ,
2020-11-20 14:06:53 -07:00
// drops richlist data for given coin
delete _richlist : function ( coin , cb ) {
Richlist . findOneAndRemove ( { coin : coin } , function ( err , exists ) {
2021-03-17 17:54:09 -06:00
if ( exists )
2020-11-20 14:06:53 -07:00
return cb ( true ) ;
2021-03-17 17:54:09 -06:00
else
2020-11-20 14:06:53 -07:00
return cb ( false ) ;
} ) ;
} ,
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
// checks richlist data exists for given coin
check _richlist : function ( coin , cb ) {
Richlist . findOne ( { coin : coin } , function ( err , exists ) {
2021-03-17 17:54:09 -06:00
if ( exists )
2019-05-27 10:33:22 -07:00
return cb ( true ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( false ) ;
} ) ;
} ,
create _heavy : function ( coin , cb ) {
var newHeavy = new Heavy ( {
2021-03-17 17:54:09 -06:00
coin : coin
2019-05-27 10:33:22 -07:00
} ) ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
newHeavy . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
} else {
2021-01-22 15:04:32 -07:00
console . log ( "initial heavycoin entry created for %s" , coin ) ;
2019-05-27 10:33:22 -07:00
return cb ( ) ;
}
} ) ;
} ,
check _heavy : function ( coin , cb ) {
Heavy . findOne ( { coin : coin } , function ( err , exists ) {
2021-03-17 17:54:09 -06:00
if ( exists )
2019-05-27 10:33:22 -07:00
return cb ( true ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( false ) ;
} ) ;
} ,
get _heavy : function ( coin , cb ) {
Heavy . findOne ( { coin : coin } , function ( err , heavy ) {
2021-03-17 17:54:09 -06:00
if ( heavy )
2019-05-27 10:33:22 -07:00
return cb ( heavy ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
} ) ;
} ,
2021-01-22 15:04:32 -07:00
get _distribution : function ( richlist , stats , cb ) {
2019-05-27 10:33:22 -07:00
var distribution = {
supply : stats . supply ,
t _1 _25 : { percent : 0 , total : 0 } ,
t _26 _50 : { percent : 0 , total : 0 } ,
t _51 _75 : { percent : 0 , total : 0 } ,
t _76 _100 : { percent : 0 , total : 0 } ,
t _101plus : { percent : 0 , total : 0 }
} ;
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
lib . syncLoop ( richlist . balance . length , function ( loop ) {
var i = loop . iteration ( ) ;
var count = i + 1 ;
var percentage = ( ( richlist . balance [ i ] . balance / 100000000 ) / stats . supply ) * 100 ;
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
if ( count <= 25 ) {
distribution . t _1 _25 . percent = distribution . t _1 _25 . percent + percentage ;
distribution . t _1 _25 . total = distribution . t _1 _25 . total + ( richlist . balance [ i ] . balance / 100000000 ) ;
}
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
if ( count <= 50 && count > 25 ) {
distribution . t _26 _50 . percent = distribution . t _26 _50 . percent + percentage ;
distribution . t _26 _50 . total = distribution . t _26 _50 . total + ( richlist . balance [ i ] . balance / 100000000 ) ;
}
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
if ( count <= 75 && count > 50 ) {
distribution . t _51 _75 . percent = distribution . t _51 _75 . percent + percentage ;
distribution . t _51 _75 . total = distribution . t _51 _75 . total + ( richlist . balance [ i ] . balance / 100000000 ) ;
}
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
if ( count <= 100 && count > 75 ) {
distribution . t _76 _100 . percent = distribution . t _76 _100 . percent + percentage ;
distribution . t _76 _100 . total = distribution . t _76 _100 . total + ( richlist . balance [ i ] . balance / 100000000 ) ;
}
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
loop . next ( ) ;
2021-01-22 15:04:32 -07:00
} , function ( ) {
distribution . t _101plus . percent = parseFloat ( 100 - distribution . t _76 _100 . percent - distribution . t _51 _75 . percent - distribution . t _26 _50 . percent - distribution . t _1 _25 . percent - ( settings . richlist _page . burned _coins . include _burned _coins _in _distribution == true && richlist . burned > 0 ? ( ( richlist . burned / 100000000 ) / stats . supply ) * 100 : 0 ) ) . toFixed ( 2 ) ;
distribution . t _101plus . total = parseFloat ( distribution . supply - distribution . t _76 _100 . total - distribution . t _51 _75 . total - distribution . t _26 _50 . total - distribution . t _1 _25 . total - ( settings . richlist _page . burned _coins . include _burned _coins _in _distribution == true && richlist . burned > 0 ? ( richlist . burned / 100000000 ) : 0 ) ) . toFixed ( 8 ) ;
2019-05-27 10:33:22 -07:00
distribution . t _1 _25 . percent = parseFloat ( distribution . t _1 _25 . percent ) . toFixed ( 2 ) ;
distribution . t _1 _25 . total = parseFloat ( distribution . t _1 _25 . total ) . toFixed ( 8 ) ;
distribution . t _26 _50 . percent = parseFloat ( distribution . t _26 _50 . percent ) . toFixed ( 2 ) ;
distribution . t _26 _50 . total = parseFloat ( distribution . t _26 _50 . total ) . toFixed ( 8 ) ;
distribution . t _51 _75 . percent = parseFloat ( distribution . t _51 _75 . percent ) . toFixed ( 2 ) ;
distribution . t _51 _75 . total = parseFloat ( distribution . t _51 _75 . total ) . toFixed ( 8 ) ;
distribution . t _76 _100 . percent = parseFloat ( distribution . t _76 _100 . percent ) . toFixed ( 2 ) ;
distribution . t _76 _100 . total = parseFloat ( distribution . t _76 _100 . total ) . toFixed ( 8 ) ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
return cb ( distribution ) ;
} ) ;
} ,
2020-12-31 15:19:48 -07:00
2021-01-22 15:04:32 -07:00
// updates heavycoin stats
2019-05-27 10:33:22 -07:00
// height: current block height, count: amount of votes to store
update _heavy : function ( coin , height , count , cb ) {
var newVotes = [ ] ;
2020-12-31 15:19:48 -07:00
2019-05-27 10:33:22 -07:00
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 ) {
2021-01-22 15:04:32 -07:00
module . exports . get _stats ( settings . coin . name , function ( stats ) {
2019-05-27 10:33:22 -07:00
lib . get _estnext ( function ( estnext ) {
lib . get _nextin ( function ( nextin ) {
lib . syncLoop ( count , function ( loop ) {
var i = loop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
2020-12-31 15:19:48 -07:00
lib . get _blockhash ( height - i , function ( hash ) {
2019-05-27 10:33:22 -07:00
lib . get _block ( hash , function ( block ) {
2020-12-31 15:19:48 -07:00
newVotes . push ( { count : height - i , reward : block . reward , vote : ( block && block . vote ? block . vote : 0 ) } ) ;
2019-05-27 10:33:22 -07:00
loop . next ( ) ;
} ) ;
} ) ;
2020-12-31 15:19:48 -07:00
} , function ( ) {
2019-06-07 20:05:28 -06:00
Heavy . updateOne ( { coin : coin } , {
2020-12-07 21:32:43 -07:00
lvote : ( vote ? vote : 0 ) ,
reward : ( reward ? reward : 0 ) ,
2021-01-22 15:04:32 -07:00
supply : ( stats && stats . supply ? stats . supply : 0 ) ,
2020-12-07 21:32:43 -07:00
cap : ( maxmoney ? maxmoney : 0 ) ,
estnext : ( estnext ? estnext : 0 ) ,
phase : ( phase ? phase : 'N/A' ) ,
maxvote : ( maxvote ? maxvote : 0 ) ,
nextin : ( nextin ? nextin : 'N/A' ) ,
2020-12-31 15:19:48 -07:00
votes : newVotes
2019-05-27 10:33:22 -07:00
} , function ( ) {
2020-12-31 15:19:48 -07:00
// update reward_last_updated value
2021-01-22 15:04:32 -07:00
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' ) ;
2020-12-31 15:19:48 -07:00
return cb ( ) ;
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ) ;
} ,
// updates market data for given market; called by sync.js
2021-01-22 15:04:32 -07:00
update _markets _db : function ( market , coin _symbol , pair _symbol , cb ) {
2020-12-08 22:52:15 -07:00
// check if market exists
if ( fs . existsSync ( './lib/markets/' + market + '.js' ) ) {
2021-01-22 15:04:32 -07:00
get _market _data ( market , coin _symbol , pair _symbol , function ( err , obj ) {
// check if there was an error with getting market data
2020-12-08 22:52:15 -07:00
if ( err == null ) {
2021-01-22 15:04:32 -07:00
// update the market collection for the current market and trading pair combination
Markets . updateOne ( { market : market , coin _symbol : coin _symbol , pair _symbol : pair _symbol } , {
2020-12-08 22:52:15 -07:00
chartdata : JSON . stringify ( obj . chartdata ) ,
buys : obj . buys ,
sells : obj . sells ,
history : obj . trades ,
summary : obj . stats
} , function ( ) {
2021-01-24 15:56:45 -07:00
// check if this is the default market and trading pair and that the price is recorded in BTC
if ( market == settings . markets _page . default _exchange . exchange _name && settings . markets _page . default _exchange . trading _pair . toUpperCase ( ) == coin _symbol . toUpperCase ( ) + '/' + pair _symbol . toUpperCase ( ) && pair _symbol . toUpperCase ( ) == 'BTC' ) {
2021-01-22 15:04:32 -07:00
// this is the default market so update the last price stats
Stats . updateOne ( { coin : settings . coin . name } , {
2021-03-17 17:54:09 -06:00
last _price : obj . stats . last
2021-01-22 15:04:32 -07:00
} , function ( ) {
// finished updating market data
2020-12-08 22:52:15 -07:00
return cb ( null ) ;
} ) ;
} else {
2021-01-22 15:04:32 -07:00
// this is not the default market so we are finished updating market data
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
2020-12-08 22:52:15 -07:00
}
} ) ;
} else {
2021-01-22 15:04:32 -07:00
// an error occurred with getting market data so return the error msg
2020-12-08 22:52:15 -07:00
return cb ( err ) ;
}
} ) ;
} else {
// market does not exist
return cb ( 'market is not installed' ) ;
}
2019-05-27 10:33:22 -07:00
} ,
2021-01-22 15:04:32 -07:00
2019-05-27 10:33:22 -07:00
get _last _usd _price : function ( cb ) {
2021-01-22 15:04:32 -07:00
// check if the default market price is enabled and being recorded in BTC
if ( settings . markets _page . exchanges [ settings . markets _page . default _exchange . exchange _name ] . enabled == true && settings . markets _page . exchanges [ settings . markets _page . default _exchange . exchange _name ] . trading _pairs . findIndex ( p => p . toLowerCase ( ) . indexOf ( '/btc' ) > - 1 ) > - 1 ) {
// convert btc to usd via coindesk api
coindesk . get _data ( function ( err , last _usd ) {
// get current stats
Stats . findOne ( { coin : settings . coin . name } , function ( err , stats ) {
// update the last usd price
Stats . updateOne ( { coin : settings . coin . name } , {
2021-03-17 17:54:09 -06:00
last _usd _price : ( last _usd * stats . last _price )
2021-01-22 15:04:32 -07:00
} , function ( ) {
return cb ( null ) ;
} ) ;
} ) ;
} ) ;
} else {
// only btc conversion supported so just exit without updating last price for now
return cb ( null ) ;
}
2019-05-27 10:33:22 -07:00
} ,
// updates stats data for given coin; called by sync.js
update _db : function ( coin , cb ) {
lib . get _blockcount ( function ( count ) {
2021-02-03 20:54:15 -07:00
// check to ensure count is a positive number
if ( ! count || ( count != null && typeof count === 'number' && count < 0 ) ) {
2019-05-27 10:33:22 -07:00
console . log ( 'Unable to connect to explorer API' ) ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
return cb ( false ) ;
}
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
lib . get _supply ( function ( supply ) {
2019-05-27 10:33:22 -07:00
lib . get _connectioncount ( function ( connections ) {
2020-12-03 14:16:34 -07:00
Stats . findOne ( { coin : coin } , function ( err , stats ) {
if ( stats ) {
Stats . updateOne ( { coin : coin } , {
coin : coin ,
count : count ,
2020-12-07 21:32:43 -07:00
supply : ( supply ? supply : 0 ) ,
connections : ( connections ? connections : 0 )
2020-12-03 14:16:34 -07:00
} , function ( err ) {
2021-03-17 17:54:09 -06:00
if ( err )
2020-12-03 14:16:34 -07:00
console . log ( "Error during Stats Update: " , err ) ;
2021-03-17 17:54:09 -06:00
2020-12-03 14:16:34 -07:00
return cb ( {
coin : coin ,
count : count ,
2020-12-07 21:32:43 -07:00
supply : ( supply ? supply : 0 ) ,
connections : ( connections ? connections : 0 ) ,
2020-12-03 14:16:34 -07:00
last : ( stats . last ? stats . last : 0 ) ,
txes : ( stats . txes ? stats . txes : 0 )
} ) ;
} ) ;
} else {
console . log ( "Error during Stats Update: " , ( err ? err : 'cannot find stats collection' ) ) ;
return cb ( false ) ;
2020-11-22 20:40:15 -07:00
}
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
} ) ;
} ) ;
} ,
// updates tx, address & richlist db's; called by sync.js
2020-12-03 14:16:34 -07:00
update _tx _db : function ( coin , start , end , txes , timeout , cb ) {
2021-01-22 15:04:32 -07:00
var complete = false ;
var blocks _to _scan = [ ] ;
var task _limit _blocks = settings . sync . block _parallel _tasks ;
var task _limit _txs = 1 ;
2021-03-17 17:54:09 -06:00
// fix for invalid block height (skip genesis block as it should not have valid txs)
if ( typeof start === 'undefined' || start < 1 )
start = 1 ;
if ( task _limit _blocks < 1 )
task _limit _blocks = 1 ;
for ( i = start ; i < ( end + 1 ) ; i ++ )
2021-01-22 15:04:32 -07:00
blocks _to _scan . push ( i ) ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
async . eachLimit ( blocks _to _scan , task _limit _blocks , function ( block _height , next _block ) {
if ( block _height % settings . sync . save _stats _after _sync _blocks === 0 ) {
Stats . updateOne ( { coin : coin } , {
last : block _height - 1 ,
txes : txes
} , function ( ) { } ) ;
}
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
lib . get _blockhash ( block _height , function ( blockhash ) {
if ( blockhash ) {
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 ) {
2021-03-17 17:54:09 -06:00
if ( tx ) {
2021-01-22 15:04:32 -07:00
setTimeout ( function ( ) {
tx = null ;
next _tx ( ) ;
} , timeout ) ;
} else {
save _tx ( txid , block _height , function ( err , tx _has _vout ) {
if ( err )
console . log ( err ) ;
else
console . log ( '%s: %s' , block _height , txid ) ;
if ( tx _has _vout )
txes ++ ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
setTimeout ( function ( ) {
tx = null ;
next _tx ( ) ;
2020-11-22 15:00:47 -07:00
} , timeout ) ;
2019-05-27 10:33:22 -07:00
} ) ;
}
} ) ;
2021-01-22 15:04:32 -07:00
} , function ( ) {
setTimeout ( function ( ) {
blockhash = null ;
block = null ;
2020-11-22 15:00:47 -07:00
next _block ( ) ;
} , timeout ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-22 15:04:32 -07:00
} else {
console . log ( 'block not found: %s' , blockhash ) ;
2021-03-17 17:54:09 -06:00
2021-01-22 15:04:32 -07:00
setTimeout ( function ( ) {
next _block ( ) ;
} , timeout ) ;
}
2019-05-27 10:33:22 -07:00
} ) ;
2021-01-22 15:04:32 -07:00
} else {
setTimeout ( function ( ) {
next _block ( ) ;
} , timeout ) ;
}
} ) ;
} , function ( ) {
Stats . updateOne ( { coin : coin } , {
last : end ,
txes : txes
} , function ( ) {
return cb ( ) ;
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ,
create _peer : function ( params , cb ) {
var newPeer = new Peers ( params ) ;
2021-03-17 17:54:09 -06:00
2019-05-27 10:33:22 -07:00
newPeer . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
2021-03-17 17:54:09 -06:00
} else
2019-05-27 10:33:22 -07:00
return cb ( ) ;
} ) ;
} ,
find _peer : function ( address , cb ) {
Peers . findOne ( { address : address } , function ( err , peer ) {
2021-03-17 17:54:09 -06:00
if ( err )
2019-05-27 10:33:22 -07:00
return cb ( null ) ;
2021-03-17 17:54:09 -06:00
else {
if ( peer )
return cb ( peer ) ;
else
return cb ( null )
2019-05-27 10:33:22 -07:00
}
2021-03-17 17:54:09 -06:00
} ) ;
2019-05-27 10:33:22 -07:00
} ,
2020-11-20 14:49:14 -07:00
drop _peer : function ( address , cb ) {
Peers . deleteOne ( { address : address } , function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
2021-03-17 17:54:09 -06:00
} else
return cb ( ) ;
} ) ;
2020-11-20 14:49:14 -07:00
} ,
drop _peers : function ( cb ) {
Peers . deleteMany ( { } , function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
2021-03-17 17:54:09 -06:00
} else
return cb ( ) ;
} ) ;
2020-11-20 14:49:14 -07:00
} ,
2019-05-27 10:33:22 -07:00
get _peers : function ( cb ) {
Peers . find ( { } , function ( err , peers ) {
2021-03-17 17:54:09 -06:00
if ( err )
2019-05-27 10:33:22 -07:00
return cb ( [ ] ) ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
return cb ( peers ) ;
} ) ;
2020-12-08 22:52:15 -07:00
} ,
2020-12-30 18:22:02 -07:00
// determine if masternode exists and save masternode to collection
save _masternode : function ( raw _masternode , cb ) {
// lookup masternode in local collection
module . exports . find _masternode ( raw _masternode . txhash , raw _masternode . outidx , function ( masternode ) {
// determine if the claim address feature is enabled
2021-01-22 15:04:32 -07:00
if ( settings . claim _address _page . enabled == true ) {
2020-12-30 18:22:02 -07:00
// claim address is enabled so lookup the address claim name
find _address ( raw _masternode . addr , false , function ( address ) {
if ( address ) {
// save claim name to masternode obejct
raw _masternode . claim _name = address . name ;
} else {
// save blank claim name to masternode obejct
raw _masternode . claim _name = '' ;
}
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
// add/update the masternode
module . exports . add _update _masternode ( raw _masternode , ( masternode == null ) , function ( success ) {
return cb ( success ) ;
} ) ;
} ) ;
} else {
// claim address is disabled so add/update the masternode
module . exports . add _update _masternode ( raw _masternode , ( masternode == null ) , function ( success ) {
return cb ( success ) ;
} ) ;
}
} ) ;
} ,
// add or update a single masternode
add _update _masternode ( masternode , add , cb ) {
if ( ! masternode . txhash == null || ! masternode . outidx == null ) {
console . log ( 'Masternode Update - TX or Outidx is missing' ) ;
console . log ( masternode . txhash ) ;
console . log ( masternode . outidx ) ;
2021-03-17 17:54:09 -06:00
2020-12-30 18:22:02 -07:00
return cb ( false ) ;
} else {
var mn = new Masternode ( {
rank : masternode . rank ,
network : masternode . network ,
txhash : masternode . txhash ,
outidx : masternode . outidx ,
status : masternode . status ,
addr : masternode . addr ,
version : masternode . version ,
lastseen : masternode . lastseen ,
activetime : masternode . activetime ,
lastpaid : masternode . lastpaid ,
claim _name : ( masternode . claim _name == null ? '' : masternode . claim _name )
} ) ;
if ( add ) {
// add new masternode to collection
mn . save ( function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( false ) ;
} else
return cb ( true ) ;
} ) ;
} else {
// update existing masternode in local collection
Masternode . updateOne ( { txhash : masternode . txhash , outidx : masternode . outidx } , masternode , function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( false ) ;
} else
return cb ( true ) ;
} ) ;
}
}
} ,
// find masternode by txid and offset
find _masternode : function ( txhash , outidx , cb ) {
Masternode . findOne ( { txhash : txhash , outidx : outidx } , function ( err , masternode ) {
if ( err )
return cb ( null ) ;
else {
if ( masternode )
return cb ( masternode ) ;
else
return cb ( null ) ;
}
} ) ;
} ,
// remove masternodes older than 24 hours
remove _old _masternodes : function ( cb ) {
Masternode . deleteMany ( { lastseen : { $lte : ( Math . floor ( Date . now ( ) / 1000 ) - 86400 ) } } , function ( err ) {
if ( err ) {
console . log ( err ) ;
return cb ( ) ;
} else
return cb ( ) ;
} ) ;
} ,
// get the list of masternodes from local collection
get _masternodes : function ( cb ) {
Masternode . find ( { } , function ( err , masternodes ) {
if ( err )
return cb ( [ ] ) ;
else
return cb ( masternodes ) ;
} ) ;
} ,
2020-12-30 20:27:42 -07:00
get _masternode _rewards : function ( mnPayees , since , cb ) {
Tx . aggregate ( [
{ $match : {
"blockindex" : { $gt : Number ( since ) } ,
"vin" : [ ]
} } ,
{ "$unwind" : "$vout" } ,
{ $match : {
"vout.addresses" : { $in : [ mnPayees ] }
} }
] , function ( err , data ) {
if ( err ) {
console . log ( err ) ;
return cb ( null ) ;
} else
return cb ( data ) ;
} ) ;
} ,
get _masternode _rewards _totals : function ( mnPayees , since , cb ) {
Tx . aggregate ( [
{ $match : {
"blockindex" : { $gt : Number ( since ) } ,
"vin" : [ ]
} } ,
{ "$unwind" : "$vout" } ,
{ $match : {
"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 ) ) ;
} ) ;
} ,
2020-12-30 18:22:02 -07:00
// updates last_updated stats; called by sync.js
update _last _updated _stats : function ( coin , param , cb ) {
2020-12-31 15:19:48 -07:00
if ( param . blockchain _last _updated ) {
// update blockchain last updated date
Stats . updateOne ( { coin : coin } , {
blockchain _last _updated : param . blockchain _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
} else if ( param . reward _last _updated ) {
// update reward last updated date
Stats . updateOne ( { coin : coin } , {
reward _last _updated : param . reward _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
} else if ( param . masternodes _last _updated ) {
2020-12-30 18:22:02 -07:00
// update masternode last updated date
Stats . updateOne ( { coin : coin } , {
masternodes _last _updated : param . masternodes _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
2020-12-31 15:19:48 -07:00
} else if ( param . network _last _updated ) {
// update network last updated date
Stats . updateOne ( { coin : coin } , {
network _last _updated : param . network _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
} else if ( param . richlist _last _updated ) {
// update richlist last updated date
Stats . updateOne ( { coin : coin } , {
richlist _last _updated : param . richlist _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
} else if ( param . markets _last _updated ) {
// update markets last updated date
Stats . updateOne ( { coin : coin } , {
markets _last _updated : param . markets _last _updated
} , function ( ) {
return cb ( true ) ;
} ) ;
2020-12-30 18:22:02 -07:00
} else {
// invalid option
return cb ( false ) ;
}
} ,
2020-12-23 18:40:10 -07:00
populate _claim _address _names : function ( tx , cb ) {
var addresses = [ ] ;
// loop through vin addresses
tx . vin . forEach ( function ( vin ) {
// check if this address already exists
if ( addresses . indexOf ( vin . addresses ) == - 1 ) {
// add address to array
addresses . push ( vin . addresses ) ;
}
} ) ;
// loop through vout addresses
tx . vout . forEach ( function ( vout ) {
// check if this address already exists
if ( addresses . indexOf ( vout . addresses ) == - 1 ) {
// add address to array
addresses . push ( vout . addresses ) ;
}
} ) ;
// loop through address array
lib . syncLoop ( addresses . length , function ( loop ) {
var a = loop . iteration ( ) ;
module . exports . get _address ( addresses [ a ] , false , function ( address ) {
if ( address && address . name != null && address . name != '' ) {
// look for address in vin
for ( v = 0 ; v < tx . vin . length ; v ++ ) {
// check if this is the correct address
if ( tx . vin [ v ] . addresses == address . a _id ) {
// add claim name to array
tx . vin [ v ] [ 'claim_name' ] = address . name ;
}
}
// look for address in vout
for ( v = 0 ; v < tx . vout . length ; v ++ ) {
// check if this is the correct address
if ( tx . vout [ v ] . addresses == address . a _id ) {
// add claim name to array
tx . vout [ v ] [ 'claim_name' ] = address . name ;
}
}
}
loop . next ( ) ;
} ) ;
} , function ( ) {
// return modified tx object
return cb ( tx ) ;
} ) ;
} ,
2020-12-08 22:52:15 -07:00
fs : fs
2020-11-20 14:06:53 -07:00
} ;