bitcore-node-zcash/Sync.js

220 lines
5.1 KiB
JavaScript
Raw Normal View History

2014-01-07 10:21:59 -08:00
require('classtool');
function spec(b) {
var mongoose = require('mongoose');
var util = require('util');
var RpcClient = require('bitcore/RpcClient').class();
var networks = require('bitcore/networks');
2014-01-07 11:49:42 -08:00
var async = require('async');
2014-01-07 10:21:59 -08:00
var config = require('./config/config');
var Block = require('./app/models/Block');
2014-01-07 11:49:42 -08:00
var Transaction=require('./app/models/Transaction');
2014-01-07 10:21:59 -08:00
function Sync(config) {
this.network = config.networkName == 'testnet' ? networks.testnet : networks.livenet;
}
2014-01-07 20:40:57 -08:00
var progress_bar = function(string, current, total) {
console.log( util.format("\t%s %d/%d [%d%%]",
string, current, total, parseInt(100 * current/total))
);
}
2014-01-07 10:21:59 -08:00
Sync.prototype.getNextBlock = function (blockHash,cb) {
var that = this;
if ( !blockHash ) {
return cb();
}
this.rpc.getBlock(blockHash, function(err, blockInfo) {
2014-01-07 20:37:29 -08:00
if (err) return cb(err);
2014-01-07 10:21:59 -08:00
if ( ! ( blockInfo.result.height % 1000) ) {
var h = blockInfo.result.height,
d = blockInfo.result.confirmations;
2014-01-07 20:40:57 -08:00
progress_bar('height', h, h + d);
2014-01-07 10:21:59 -08:00
}
Block.create( blockInfo.result, function(err, inBlock) {
// E11000 => already exists
if (err && ! err.toString().match(/E11000/)) {
return cb(err);
}
2014-01-07 11:49:42 -08:00
if (inBlock) {
inBlock.explodeTransactions(function (err) {
return that.getNextBlock(blockInfo.result.nextblockhash, cb);
});
}
else
return that.getNextBlock(blockInfo.result.nextblockhash, cb);
2014-01-07 10:21:59 -08:00
});
});
}
Sync.prototype.syncBlocks = function (reindex, cb) {
var that = this;
var genesisHash = this.network.genesisBlock.hash.reverse().toString('hex');
2014-01-07 20:37:29 -08:00
console.log("Syncing Blocks...");
2014-01-07 10:21:59 -08:00
if (reindex)
return this.getNextBlock(genesisHash, cb);
Block.findOne({}, {}, { sort: { 'confirmations' : 1 } }, function(err, block) {
if (err) return cb(err);
var nextHash =
block && block.hash
? block.hash
: genesisHash
;
2014-01-07 20:37:29 -08:00
console.log('\tStarting at hash: ' + nextHash);
2014-01-07 10:21:59 -08:00
return that.getNextBlock(nextHash, cb);
});
}
2014-01-07 20:37:29 -08:00
Sync.prototype.syncTXs = function (reindex, cb) {
var that = this;
console.log("Syncing TXs...");
if (reindex) {
// TODO?
}
2014-01-07 20:40:57 -08:00
Transaction.find({blockhash: null}, function(err, txs) {
2014-01-07 20:37:29 -08:00
if (err) return cb(err);
var read = 0;
var pull = 0;
var write = 0;
var total = txs.length;
console.log("\tneed to pull %d txs", total);
if (!total) return cb();
async.each(txs,
function(tx, next){
if (! tx.txid) {
console.log("NO TXID skipping...", tx);
return next();
}
if ( ! ( read++ % 1000) )
progress_bar('read', read, total);
that.rpc.getRawTransaction(tx.txid, 1, function(err, txInfo) {
if ( ! ( pull++ % 1000) )
progress_bar('\tpull', pull, total);
if (!err && txInfo) {
Transaction.update({txid: tx.txid}, txInfo.result, function(err) {
if (err) return next(err);
if ( ! ( write++ % 1000) )
progress_bar('\t\twrite', write, total);
return next();
});
}
else return next();
});
},
function(err){
if (err) return cb(err);
return cb(err);
}
);
});
}
2014-01-07 11:49:42 -08:00
Sync.prototype.start = function (opts, next) {
2014-01-07 10:21:59 -08:00
mongoose.connect(config.db);
var db = mongoose.connection;
this.rpc = new RpcClient(config.bitcoind);
var that = this;
db.on('error', console.error.bind(console, 'connection error:'));
2014-01-07 11:49:42 -08:00
db.once('open', function (){
async.series([
function(cb){
if (opts.destroy) {
console.log("Deleting Blocks...");
return Block.remove().exec(cb);
2014-01-07 11:49:42 -08:00
}
return cb();
2014-01-07 11:49:42 -08:00
},
function(cb){
if (opts.destroy) {
console.log("Deleting TXs...");
return Transaction.remove().exec(cb);
2014-01-07 11:49:42 -08:00
}
return cb();
2014-01-07 11:49:42 -08:00
},
function(cb) {
2014-01-07 20:37:29 -08:00
if (! opts.skip_blocks) {
that.syncBlocks(opts.reindex, function(err) {
if (err) {
return cb(err);
}
console.log("\tBlocks done.");
return cb();
});
}
else {
2014-01-07 11:49:42 -08:00
return cb();
2014-01-07 20:37:29 -08:00
}
},
function(cb) {
if (! opts.skip_txs) {
that.syncTXs(opts.reindex, function(err) {
if (err) {
return cb(err);
}
return cb();
});
}
else {
return cb();
}
},
function(cb) {
db.close();
return cb();
},
2014-01-07 11:49:42 -08:00
],
function(err) {
2014-01-07 20:37:29 -08:00
if (err) {
db.close();
return next(err);
}
2014-01-07 11:49:42 -08:00
return next();
2014-01-07 10:21:59 -08:00
});
});
}
return Sync;
};
module.defineClass(spec);