2021-03-17 17:54:09 -06:00
var mongoose = require ( 'mongoose' ) ,
lib = require ( '../lib/explorer' ) ,
db = require ( '../lib/database' ) ,
Tx = require ( '../models/tx' ) ,
Address = require ( '../models/address' ) ,
AddressTx = require ( '../models/addresstx' ) ,
Richlist = require ( '../models/richlist' ) ,
Stats = require ( '../models/stats' ) ,
2022-07-17 16:49:02 -06:00
settings = require ( '../lib/settings' ) ,
async = require ( 'async' ) ;
2019-05-27 10:33:22 -07:00
var mode = 'update' ;
var database = 'index' ;
2021-11-21 19:15:42 -07:00
var block _start = 1 ;
2022-04-30 20:53:10 -06:00
var lockCreated = false ;
2022-07-17 16:49:02 -06:00
var stopSync = false ;
// prevent stopping of the sync script to be able to gracefully shut down
process . on ( 'SIGINT' , ( ) => {
console . log ( 'Stopping sync process.. Please wait..' ) ;
stopSync = true ;
} ) ;
// prevent killing of the sync script to be able to gracefully shut down
process . on ( 'SIGTERM' , ( ) => {
console . log ( 'Stopping sync process.. Please wait..' ) ;
stopSync = true ;
} ) ;
2019-05-27 10:33:22 -07:00
// displays usage and exits
function usage ( ) {
2022-04-23 11:28:32 -06:00
console . log ( 'Usage: /path/to/node scripts/sync.js [mode]' ) ;
2019-05-27 10:33:22 -07:00
console . log ( '' ) ;
2020-12-04 10:59:58 -07:00
console . log ( 'Mode: (required)' ) ;
2020-12-03 14:16:34 -07:00
console . log ( 'update Updates index from last sync to current block' ) ;
console . log ( 'check Checks index for (and adds) any missing transactions/addresses' ) ;
2021-11-21 19:15:42 -07:00
console . log ( ' Optional parameter: block number to start checking from' ) ;
2020-12-03 14:16:34 -07:00
console . log ( 'reindex Clears index then resyncs from genesis to current block' ) ;
2021-03-17 17:54:09 -06:00
console . log ( 'reindex-rich Clears and recreates the richlist data' ) ;
2020-12-03 14:16:34 -07:00
console . log ( 'reindex-txcount Rescan and flatten the tx count value for faster access' ) ;
2021-01-24 15:26:17 -07:00
console . log ( 'reindex-last Rescan and flatten the last blockindex value for faster access' ) ;
2020-12-04 10:59:58 -07:00
console . log ( 'market Updates market summaries, orderbooks, trade history + charts' ) ;
console . log ( 'peers Updates peer info based on local wallet connections' ) ;
2020-12-30 18:22:02 -07:00
console . log ( 'masternodes Updates the list of active masternodes on the network' ) ;
2019-05-27 10:33:22 -07:00
console . log ( '' ) ;
2020-12-04 10:59:58 -07:00
console . log ( 'Notes:' ) ;
console . log ( '- \'current block\' is the latest created block when script is executed.' ) ;
console . log ( '- The market + peers databases only support (& defaults to) reindex mode.' ) ;
2021-11-21 13:22:24 -07:00
console . log ( '- If check mode finds missing data (other than new data since last sync),' ) ;
console . log ( ' this likely means that sync.update_timeout in settings.json is set too low.' ) ;
2019-05-27 10:33:22 -07:00
console . log ( '' ) ;
2022-04-30 20:53:10 -06:00
process . exit ( 100 ) ;
}
// exit function used to cleanup before finishing script
function exit ( exitCode ) {
// always disconnect mongo connection
mongoose . disconnect ( ) ;
// only remove sync lock if it was created in this session
if ( ! lockCreated || lib . remove _lock ( database ) == true ) {
// clean exit with previous exit code
process . exit ( exitCode ) ;
} else {
// error removing lock
process . exit ( 1 ) ;
}
}
2022-07-17 16:49:02 -06:00
// updates tx, address & richlist db's
function update _tx _db ( coin , start , end , txes , timeout , check _only , cb ) {
var complete = false ;
var blocks _to _scan = [ ] ;
var task _limit _blocks = settings . sync . block _parallel _tasks ;
var task _limit _txs = 1 ;
// 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 ++ )
blocks _to _scan . push ( i ) ;
async . eachLimit ( blocks _to _scan , task _limit _blocks , function ( block _height , next _block ) {
if ( ! check _only && block _height % settings . sync . save _stats _after _sync _blocks === 0 ) {
Stats . updateOne ( { coin : coin } , {
last : block _height - 1 ,
txes : txes
} , function ( ) { } ) ;
} else if ( check _only ) {
console . log ( 'Checking block ' + block _height + '...' ) ;
}
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 ) {
if ( tx ) {
setTimeout ( function ( ) {
tx = null ;
// check if the script is stopping
if ( stopSync ) {
// stop the loop
next _tx ( { } ) ;
} else
next _tx ( ) ;
} , timeout ) ;
} else {
db . 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 ++ ;
setTimeout ( function ( ) {
tx = null ;
// check if the script is stopping
if ( stopSync ) {
// stop the loop
next _tx ( { } ) ;
} else
next _tx ( ) ;
} , timeout ) ;
} ) ;
}
} ) ;
} , function ( ) {
setTimeout ( function ( ) {
blockhash = null ;
block = null ;
// check if the script is stopping
if ( stopSync ) {
// stop the loop
next _block ( { } ) ;
} else
next _block ( ) ;
} , timeout ) ;
} ) ;
} else {
console . log ( 'Block not found: %s' , blockhash ) ;
setTimeout ( function ( ) {
// check if the script is stopping
if ( stopSync ) {
// stop the loop
next _block ( { } ) ;
} else
next _block ( ) ;
} , timeout ) ;
}
} ) ;
} else {
setTimeout ( function ( ) {
// check if the script is stopping
if ( stopSync ) {
// stop the loop
next _block ( { } ) ;
} else
next _block ( ) ;
} , timeout ) ;
}
} ) ;
} , function ( ) {
// check if the script stopped prematurely
if ( ! stopSync ) {
Stats . updateOne ( { coin : coin } , {
last : end ,
txes : txes
} , function ( ) {
return cb ( ) ;
} ) ;
} else
return cb ( ) ;
} ) ;
}
2022-04-30 20:53:10 -06:00
function update _heavy ( coin , height , count , heavycoin _enabled , cb ) {
if ( heavycoin _enabled == true ) {
db . update _heavy ( coin , height , count , function ( ) {
return cb ( true ) ;
} ) ;
} else
return cb ( false ) ;
}
function update _network _history ( height , network _history _enabled , cb ) {
if ( network _history _enabled == true ) {
db . update _network _history ( height , function ( ) {
return cb ( true ) ;
} ) ;
} else
return cb ( false ) ;
}
function check _show _sync _message ( blocks _to _sync ) {
var retVal = false ;
var filePath = './tmp/show_sync_message.tmp' ;
// Check if the sync msg should be shown
if ( blocks _to _sync > settings . sync . show _sync _msg _when _syncing _more _than _blocks ) {
// Check if the show sync stub file already exists
if ( ! db . fs . existsSync ( filePath ) ) {
// File doesn't exist, so create it now
db . fs . writeFileSync ( filePath , '' ) ;
}
retVal = true ;
}
return retVal ;
}
function get _last _usd _price ( ) {
// get the last usd price for coinstats
db . get _last _usd _price ( function ( err ) {
// check for errors
if ( err == null ) {
// update markets_last_updated value
db . update _last _updated _stats ( settings . coin . name , { markets _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
2022-07-17 16:49:02 -06:00
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Market sync was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
console . log ( 'Market sync complete' ) ;
exit ( 0 ) ;
}
2022-04-30 20:53:10 -06:00
} ) ;
} else {
// display error msg
console . log ( 'Error: %s' , err ) ;
exit ( 1 ) ;
}
} ) ;
}
/** Function that count occurrences of a substring in a string;
* @param {String} string The string
* @param {String} subString The sub string to search for
* @param {Boolean} [allowOverlapping] Optional. (Default:false)
*
* @author Vitim.us https://gist.github.com/victornpb/7736865
* @see Unit Test https://jsfiddle.net/Victornpb/5axuh96u/
* @see http://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string/7924240#7924240
*/
function occurrences ( string , subString , allowOverlapping ) {
string += "" ;
subString += "" ;
if ( subString . length <= 0 ) return ( string . length + 1 ) ;
var n = 0 ,
pos = 0 ,
step = allowOverlapping ? 1 : subString . length ;
while ( true ) {
pos = string . indexOf ( subString , pos ) ;
if ( pos >= 0 ) {
++ n ;
pos += step ;
} else break ;
}
return n ;
2019-05-27 10:33:22 -07:00
}
// check options
2022-04-23 11:28:32 -06:00
if ( process . argv [ 2 ] == null || process . argv [ 2 ] == 'index' || process . argv [ 2 ] == 'update' ) {
mode = null ;
switch ( process . argv [ 3 ] ) {
case undefined :
case null :
case 'update' :
mode = 'update' ;
break ;
case 'check' :
mode = 'check' ;
// check if the block start value was passed in and is an integer
if ( ! isNaN ( process . argv [ 4 ] ) && Number . isInteger ( parseFloat ( process . argv [ 4 ] ) ) ) {
// Check if the block start value is less than 1
if ( parseInt ( process . argv [ 4 ] ) < 1 )
block _start = 1 ;
else
block _start = parseInt ( process . argv [ 4 ] ) ;
}
break ;
case 'reindex' :
// check if readlinesync module is installed
if ( ! db . fs . existsSync ( './node_modules/readline-sync' ) ) {
const { execSync } = require ( 'child_process' ) ;
console . log ( 'Installing missing packages.. Please wait..' ) ;
// install updated packages
execSync ( 'npm update' ) ;
}
const readlineSync = require ( 'readline-sync' ) ;
console . log ( 'You are about to delete all blockchain data (transactions and addresses)' ) ;
console . log ( 'and resync from the genesis block.' ) ;
// prompt for the reindex
if ( readlineSync . keyInYN ( 'Are you sure you want to do this? ' ) ) {
// set mode to 'reindex'
2020-11-19 21:37:42 -07:00
mode = 'reindex' ;
2022-04-23 11:28:32 -06:00
} else {
console . log ( 'Process aborted. Nothing was deleted' ) ;
2022-04-30 20:53:10 -06:00
exit ( 2 ) ;
2022-04-23 11:28:32 -06:00
}
break ;
case 'reindex-rich' :
mode = 'reindex-rich' ;
break ;
case 'reindex-txcount' :
mode = 'reindex-txcount' ;
break ;
case 'reindex-last' :
mode = 'reindex-last' ;
break ;
default :
usage ( ) ;
}
2022-04-30 20:53:10 -06:00
} else if ( process . argv [ 2 ] == 'peers' || process . argv [ 2 ] == 'masternodes' )
database = process . argv [ 2 ] ;
else if ( process . argv [ 2 ] == 'market' )
database = ` ${ process . argv [ 2 ] } s ` ;
2021-03-17 17:54:09 -06:00
else
2019-05-27 10:33:22 -07:00
usage ( ) ;
2022-04-30 20:53:10 -06:00
// check if this sync option is already running/locked
if ( lib . is _locked ( [ database ] ) == false ) {
// create a new sync lock before checking the rest of the locks to minimize problems with running scripts at the same time
lib . create _lock ( database ) ;
// ensure the lock will be deleted on exit
lockCreated = true ;
// check the backup, restore and delete locks since those functions would be problematic when updating data
if ( lib . is _locked ( [ 'backup' , 'restore' , 'delete' ] ) == false ) {
// all tests passed. OK to run sync
console . log ( "Script launched with pid: " + process . pid ) ;
if ( mode == 'update' )
console . log ( ` Syncing ${ ( database == 'index' ? 'blocks' : database ) } .. Please wait.. ` ) ;
2022-06-13 19:37:48 -06:00
var dbString = 'mongodb://' + encodeURIComponent ( settings . dbsettings . user ) ;
dbString = dbString + ':' + encodeURIComponent ( settings . dbsettings . password ) ;
2022-04-30 20:53:10 -06:00
dbString = dbString + '@' + settings . dbsettings . address ;
dbString = dbString + ':' + settings . dbsettings . port ;
dbString = dbString + '/' + settings . dbsettings . database ;
2022-12-16 19:17:37 -07:00
mongoose . set ( 'strictQuery' , true ) ;
2022-04-30 20:53:10 -06:00
mongoose . connect ( dbString , function ( err ) {
2019-05-27 10:33:22 -07:00
if ( err ) {
2022-04-30 20:53:10 -06:00
console . log ( 'Error: Unable to connect to database: %s' , dbString ) ;
exit ( 1 ) ;
} else 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.' ) ;
exit ( 1 ) ;
} else {
db . update _db ( settings . coin . name , function ( stats ) {
// check if stats returned properly
if ( stats !== false ) {
// determine which index mode to run
if ( mode == 'reindex' ) {
console . log ( 'Deleting transactions.. Please wait..' ) ;
Tx . deleteMany ( { } , function ( err ) {
console . log ( 'Transactions deleted successfully' ) ;
console . log ( 'Deleting addresses.. Please wait..' ) ;
Address . deleteMany ( { } , function ( err2 ) {
console . log ( 'Addresses deleted successfully' ) ;
console . log ( 'Deleting address transactions.. Please wait..' ) ;
AddressTx . deleteMany ( { } , function ( err3 ) {
console . log ( 'Address transactions deleted successfully' ) ;
console . log ( 'Deleting top 100 data.. Please wait..' ) ;
Richlist . updateOne ( { coin : settings . coin . name } , {
received : [ ] ,
balance : [ ]
} , function ( err3 ) {
console . log ( 'Top 100 data deleted successfully' ) ;
console . log ( 'Deleting block index.. Please wait..' ) ;
Stats . updateOne ( { coin : settings . coin . name } , {
last : 0 ,
count : 0 ,
supply : 0 ,
txes : 0 ,
blockchain _last _updated : 0 ,
richlist _last _updated : 0
} , function ( ) {
console . log ( 'Block index deleted successfully' ) ;
// Check if the sync msg should be shown
check _show _sync _message ( stats . count ) ;
console . log ( 'Starting resync of blockchain data.. Please wait..' ) ;
2022-07-17 16:49:02 -06:00
update _tx _db ( settings . coin . name , block _start , stats . count , stats . txes , settings . sync . update _timeout , false , function ( ) {
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Reindex was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
// update blockchain_last_updated value
db . update _last _updated _stats ( settings . coin . name , { blockchain _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
db . update _richlist ( 'received' , function ( ) {
db . update _richlist ( 'balance' , function ( ) {
// update richlist_last_updated value
db . update _last _updated _stats ( settings . coin . name , { richlist _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
db . get _stats ( settings . coin . name , function ( nstats ) {
// check for and update heavycoin data if applicable
update _heavy ( settings . coin . name , stats . count , 20 , settings . blockchain _specific . heavycoin . enabled , function ( heavy ) {
// check for and update network history data if applicable
update _network _history ( nstats . last , settings . network _history . enabled , function ( network _hist ) {
// always check for and remove the sync msg if exists
db . remove _sync _message ( ) ;
console . log ( 'Reindex complete (block: %s)' , nstats . last ) ;
exit ( 0 ) ;
} ) ;
2022-03-19 18:44:36 -06:00
} ) ;
2021-02-03 20:54:15 -07:00
} ) ;
2020-12-31 15:19:48 -07:00
} ) ;
} ) ;
2020-12-04 10:59:58 -07:00
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
2022-07-17 16:49:02 -06:00
}
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
} ) ;
} ) ;
2022-04-30 20:53:10 -06:00
} ) ;
} ) ;
} else if ( mode == 'check' ) {
console . log ( 'Checking blocks.. Please wait..' ) ;
2022-07-17 16:49:02 -06:00
update _tx _db ( settings . coin . name , block _start , stats . count , stats . txes , settings . sync . check _timeout , true , function ( ) {
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Block check was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
db . get _stats ( settings . coin . name , function ( nstats ) {
console . log ( 'Block check complete (block: %s)' , nstats . last ) ;
exit ( 0 ) ;
} ) ;
}
2022-04-30 20:53:10 -06:00
} ) ;
} else if ( mode == 'update' ) {
// Get the last synced block index value
var last = ( stats . last ? stats . last : 0 ) ;
// Get the total number of blocks
var count = ( stats . count ? stats . count : 0 ) ;
// Check if the sync msg should be shown
check _show _sync _message ( count - last ) ;
2022-07-17 16:49:02 -06:00
update _tx _db ( settings . coin . name , last , count , stats . txes , settings . sync . update _timeout , false , function ( ) {
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Block sync was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
// update blockchain_last_updated value
db . update _last _updated _stats ( settings . coin . name , { blockchain _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
db . update _richlist ( 'received' , function ( ) {
db . update _richlist ( 'balance' , function ( ) {
// update richlist_last_updated value
db . update _last _updated _stats ( settings . coin . name , { richlist _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
db . get _stats ( settings . coin . name , function ( nstats ) {
// check for and update heavycoin data if applicable
update _heavy ( settings . coin . name , stats . count , 20 , settings . blockchain _specific . heavycoin . enabled , function ( heavy ) {
// check for and update network history data if applicable
update _network _history ( nstats . last , settings . network _history . enabled , function ( network _hist ) {
// always check for and remove the sync msg if exists
db . remove _sync _message ( ) ;
console . log ( 'Block sync complete (block: %s)' , nstats . last ) ;
exit ( 0 ) ;
} ) ;
2021-02-03 20:54:15 -07:00
} ) ;
2020-12-31 15:19:48 -07:00
} ) ;
} ) ;
2019-05-27 10:33:22 -07:00
} ) ;
} ) ;
} ) ;
2022-07-17 16:49:02 -06:00
}
2022-04-30 20:53:10 -06:00
} ) ;
} else if ( mode == 'reindex-rich' ) {
console . log ( 'Check richlist' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . check _richlist ( settings . coin . name , function ( exists ) {
if ( exists )
console . log ( 'Richlist entry found, deleting now..' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . delete _richlist ( settings . coin . name , function ( deleted ) {
if ( deleted )
console . log ( 'Richlist entry deleted' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . create _richlist ( settings . coin . name , false , function ( ) {
console . log ( 'Richlist created' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . update _richlist ( 'received' , function ( ) {
console . log ( 'Richlist updated received' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . update _richlist ( 'balance' , function ( ) {
// update richlist_last_updated value
db . update _last _updated _stats ( settings . coin . name , { richlist _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
console . log ( 'Richlist update complete' ) ;
exit ( 0 ) ;
2020-11-20 14:06:53 -07:00
} ) ;
} ) ;
} ) ;
2020-11-22 17:00:44 -07:00
} ) ;
2022-04-30 20:53:10 -06:00
} ) ;
} ) ;
} else if ( mode == 'reindex-txcount' ) {
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 ) {
console . log ( 'Found tx count: ' + count . toString ( ) ) ;
Stats . updateOne ( { coin : settings . coin . name } , {
txes : count
} , function ( ) {
console . log ( 'Tx count update complete' ) ;
exit ( 0 ) ;
} ) ;
} ) ;
} else if ( mode == 'reindex-last' ) {
console . log ( 'Finding last blockindex.. Please wait..' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
// 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 ) {
// check if any blocks exists
if ( err != null || tx == null || tx . length == 0 ) {
console . log ( 'No blocks found. setting last blockindex to 0.' ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
Stats . updateOne ( { coin : settings . coin . name } , {
last : 0
} , function ( ) {
console . log ( 'Last blockindex update complete' ) ;
exit ( 0 ) ;
} ) ;
} else {
console . log ( 'Found last blockindex: ' + tx [ 0 ] . blockindex . toString ( ) ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
Stats . updateOne ( { coin : settings . coin . name } , {
last : tx [ 0 ] . blockindex
} , function ( ) {
console . log ( 'Last blockindex update complete' ) ;
exit ( 0 ) ;
2021-02-03 20:54:15 -07:00
} ) ;
}
2022-04-30 20:53:10 -06:00
} ) ;
}
} else {
// update_db threw an error so exit
exit ( 1 ) ;
2019-05-27 10:33:22 -07:00
}
} ) ;
2022-04-30 20:53:10 -06:00
}
} ) ;
} else if ( database == 'peers' ) {
lib . get _peerinfo ( function ( body ) {
if ( body != null ) {
lib . syncLoop ( body . length , function ( loop ) {
var i = loop . iteration ( ) ;
var address = body [ i ] . addr ;
var port = null ;
if ( occurrences ( address , ':' ) == 1 || occurrences ( address , ']:' ) == 1 ) {
// Separate the port # from the IP address
address = address . substring ( 0 , address . lastIndexOf ( ":" ) ) . replace ( "[" , "" ) . replace ( "]" , "" ) ;
port = body [ i ] . addr . substring ( body [ i ] . addr . lastIndexOf ( ":" ) + 1 ) ;
}
if ( address . indexOf ( "]" ) > - 1 ) {
// Remove [] characters from IPv6 addresses
address = address . replace ( "[" , "" ) . replace ( "]" , "" ) ;
}
2022-07-01 21:11:57 -06:00
db . find _peer ( address , port , function ( peer ) {
2022-04-30 20:53:10 -06:00
if ( peer ) {
2022-08-10 19:09:28 -06:00
if ( peer [ 'port' ] != null && ( isNaN ( peer [ 'port' ] ) || peer [ 'port' ] . length < 2 ) ) {
2022-04-30 20:53:10 -06:00
db . drop _peers ( function ( ) {
2022-08-10 19:09:28 -06:00
console . log ( 'Removing peers due to missing port information. Re-run this script to add peers again.' ) ;
2022-04-30 20:53:10 -06:00
exit ( 1 ) ;
} ) ;
2021-01-22 15:04:32 -07:00
}
2022-04-30 20:53:10 -06:00
2022-07-01 21:11:57 -06:00
// peer already exists and should be refreshed
// drop peer
db . drop _peer ( address , port , function ( ) {
// re-add the peer to refresh the data and extend the expiry date
db . create _peer ( {
address : address ,
port : port ,
protocol : peer . protocol ,
version : peer . version ,
country : peer . country ,
country _code : peer . country _code
} , function ( ) {
console . log ( 'Updated peer %s:%s [%s/%s]' , address , port . toString ( ) , ( i + 1 ) . toString ( ) , body . length . toString ( ) ) ;
2022-07-17 16:49:02 -06:00
// check if the script is stopping
if ( stopSync ) {
// stop the loop
loop . break ( true ) ;
}
2022-07-01 21:11:57 -06:00
loop . next ( ) ;
} ) ;
} ) ;
2022-04-30 20:53:10 -06:00
} else {
const rateLimitLib = require ( '../lib/ratelimit' ) ;
const rateLimit = new rateLimitLib . RateLimit ( 1 , 2000 , false ) ;
rateLimit . schedule ( function ( ) {
lib . get _geo _location ( address , function ( error , geo ) {
// check if an error was returned
if ( error ) {
console . log ( error ) ;
exit ( 1 ) ;
2022-04-30 21:27:12 -06:00
} else if ( geo == null || typeof geo != 'object' ) {
console . log ( 'Error: geolocation api did not return a valid object' ) ;
exit ( 1 ) ;
2022-04-30 20:53:10 -06:00
} else {
// add peer to collection
db . create _peer ( {
address : address ,
port : port ,
protocol : body [ i ] . version ,
version : body [ i ] . subver . replace ( '/' , '' ) . replace ( '/' , '' ) ,
country : geo . country _name ,
country _code : geo . country _code
} , function ( ) {
2022-07-01 21:11:57 -06:00
console . log ( 'Added new peer %s:%s [%s/%s]' , address , port . toString ( ) , ( i + 1 ) . toString ( ) , body . length . toString ( ) ) ;
2022-07-17 16:49:02 -06:00
// check if the script is stopping
if ( stopSync ) {
// stop the loop
loop . break ( true ) ;
}
2022-04-30 20:53:10 -06:00
loop . next ( ) ;
} ) ;
}
} ) ;
} ) ;
2021-01-22 15:04:32 -07:00
}
} ) ;
2022-04-30 20:53:10 -06:00
} , function ( ) {
// update network_last_updated value
db . update _last _updated _stats ( settings . coin . name , { network _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
2022-07-17 16:49:02 -06:00
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Peer sync was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
console . log ( 'Peer sync complete' ) ;
exit ( 0 ) ;
}
2022-04-30 20:53:10 -06:00
} ) ;
} ) ;
} else {
console . log ( 'No peers found' ) ;
exit ( 2 ) ;
}
} ) ;
} else if ( database == 'masternodes' ) {
lib . get _masternodelist ( function ( body ) {
if ( body != null ) {
var isObject = false ;
var objectKeys = null ;
// Check if the masternode data is an array or an object
if ( body . length == null ) {
// Process data as an object
objectKeys = Object . keys ( body ) ;
isObject = true ;
}
2021-01-22 15:04:32 -07:00
2022-04-30 20:53:10 -06:00
lib . syncLoop ( ( isObject ? objectKeys : body ) . length , function ( loop ) {
var i = loop . iteration ( ) ;
2021-03-17 17:54:09 -06:00
2022-04-30 20:53:10 -06:00
db . save _masternode ( ( isObject ? body [ objectKeys [ i ] ] : body [ i ] ) , function ( success ) {
2022-07-17 16:49:02 -06:00
if ( success ) {
// check if the script is stopping
if ( stopSync ) {
// stop the loop
loop . break ( true ) ;
}
2022-04-30 20:53:10 -06:00
loop . next ( ) ;
2022-07-17 16:49:02 -06:00
} else {
2022-04-30 20:53:10 -06:00
console . log ( 'Error: Cannot save masternode %s.' , ( isObject ? ( body [ objectKeys [ i ] ] . payee ? body [ objectKeys [ i ] ] . payee : 'UNKNOWN' ) : ( body [ i ] . addr ? body [ i ] . addr : 'UNKNOWN' ) ) ) ;
exit ( 1 ) ;
}
} ) ;
} , function ( ) {
db . remove _old _masternodes ( function ( cb ) {
db . update _last _updated _stats ( settings . coin . name , { masternodes _last _updated : Math . floor ( new Date ( ) / 1000 ) } , function ( cb ) {
2022-07-17 16:49:02 -06:00
// check if the script stopped prematurely
if ( stopSync ) {
console . log ( 'Masternode sync was stopped prematurely' ) ;
exit ( 1 ) ;
} else {
console . log ( 'Masternode sync complete' ) ;
exit ( 0 ) ;
}
2020-12-08 22:52:15 -07:00
} ) ;
2022-04-30 20:53:10 -06:00
} ) ;
} ) ;
} else {
console . log ( 'No masternodes found' ) ;
exit ( 2 ) ;
2019-05-27 10:33:22 -07:00
}
2020-12-04 10:59:58 -07:00
} ) ;
2022-04-30 20:53:10 -06:00
} else {
// check if market feature is enabled
if ( settings . markets _page . enabled == true ) {
var complete = 0 ;
var total _pairs = 0 ;
var exchanges = Object . keys ( settings . markets _page . exchanges ) ;
// loop through all exchanges to determine how many trading pairs must be updated
exchanges . forEach ( function ( key , index , map ) {
// check if market is enabled via settings
if ( settings . markets _page . exchanges [ key ] . enabled == true ) {
// check if market is installed/supported
if ( db . fs . existsSync ( './lib/markets/' + key + '.js' ) ) {
// add trading pairs to total
total _pairs += settings . markets _page . exchanges [ key ] . trading _pairs . length ;
// loop through all trading pairs for this market
for ( var i = 0 ; i < settings . markets _page . exchanges [ key ] . trading _pairs . length ; i ++ ) {
// ensure trading pair setting is always uppercase
settings . markets _page . exchanges [ key ] . trading _pairs [ i ] = settings . markets _page . exchanges [ key ] . trading _pairs [ i ] . toUpperCase ( ) ;
}
}
}
} ) ;
2019-06-07 20:05:28 -06:00
2022-04-30 20:53:10 -06:00
// check if there are any trading pairs to update
if ( total _pairs > 0 ) {
// initialize the rate limiter to wait 2 seconds between requests to prevent abusing external apis
var rateLimitLib = require ( '../lib/ratelimit' ) ;
var rateLimit = new rateLimitLib . RateLimit ( 1 , 2000 , false ) ;
// loop through and test all exchanges defined in the settings.json file
exchanges . forEach ( function ( key , index , map ) {
// check if market is enabled via settings
if ( settings . markets _page . exchanges [ key ] . enabled == true ) {
// check if market is installed/supported
if ( db . fs . existsSync ( './lib/markets/' + key + '.js' ) ) {
// loop through all trading pairs
settings . markets _page . exchanges [ key ] . trading _pairs . forEach ( function ( pair _key , pair _index , pair _map ) {
// split the pair data
var split _pair = pair _key . split ( '/' ) ;
// check if this is a valid trading pair
if ( split _pair . length == 2 ) {
// lookup the exchange in the market collection
db . check _market ( key , split _pair [ 0 ] , split _pair [ 1 ] , function ( mkt , exists ) {
// check if exchange trading pair exists in the market collection
if ( exists ) {
// automatically pause for 2 seconds in between requests
rateLimit . schedule ( function ( ) {
// update market data
db . update _markets _db ( key , split _pair [ 0 ] , split _pair [ 1 ] , function ( err ) {
if ( ! err ) {
console . log ( '%s[%s]: Market data updated successfully.' , key , pair _key ) ;
complete ++ ;
2022-07-17 16:49:02 -06:00
if ( complete == total _pairs || stopSync )
2022-04-30 20:53:10 -06:00
get _last _usd _price ( ) ;
} else {
console . log ( '%s[%s] Error: %s' , key , pair _key , err ) ;
complete ++ ;
2022-07-17 16:49:02 -06:00
if ( complete == total _pairs || stopSync )
2022-04-30 20:53:10 -06:00
get _last _usd _price ( ) ;
}
} ) ;
} ) ;
} else {
console . log ( 'Error: Entry for %s[%s] does not exist in markets database.' , key , pair _key ) ;
complete ++ ;
2022-07-17 16:49:02 -06:00
if ( complete == total _pairs || stopSync )
2022-04-30 20:53:10 -06:00
get _last _usd _price ( ) ;
}
} ) ;
}
} ) ;
} else {
// market not installed
console . log ( '%s market not installed' , key ) ;
complete ++ ;
2022-03-19 19:27:17 -06:00
2022-07-17 16:49:02 -06:00
if ( complete == total _pairs || stopSync )
2022-04-30 20:53:10 -06:00
get _last _usd _price ( ) ;
}
}
} ) ;
} else {
// no market trading pairs are enabled
console . log ( 'Error: No market trading pairs are enabled in settings' ) ;
exit ( 1 ) ;
}
} else {
// market page is not enabled
console . log ( 'Error: Market feature is disabled in settings' ) ;
exit ( 1 ) ;
}
}
2022-04-11 01:37:27 -06:00
} ) ;
2022-04-30 20:53:10 -06:00
} else {
// another script process is currently running
console . log ( "Sync aborted" ) ;
exit ( 2 ) ;
2020-12-05 12:39:36 -07:00
}
2022-04-30 20:53:10 -06:00
} else {
// sync process is already running
console . log ( "Sync aborted" ) ;
exit ( 2 ) ;
2019-06-07 20:05:28 -06:00
}