diff --git a/Sync.js b/Sync.js new file mode 100644 index 0000000..df30060 --- /dev/null +++ b/Sync.js @@ -0,0 +1,99 @@ +require('classtool'); + +function spec(b) { + var mongoose = require('mongoose'); + var util = require('util'); + + var RpcClient = require('bitcore/RpcClient').class(); + var networks = require('bitcore/networks'); + + var config = require('./config/config'); + var Block = require('./app/models/Block'); + + function Sync(config) { + this.network = config.networkName == 'testnet' ? networks.testnet : networks.livenet; + } + + Sync.prototype.getNextBlock = function (blockHash,cb) { + var that = this; + + if ( !blockHash ) { + return cb(); + } + + this.rpc.getBlock(blockHash, function(err, blockInfo) { + if (err) { + return cb(err); + } + + if ( ! ( blockInfo.result.height % 1000) ) { + var h = blockInfo.result.height, + d = blockInfo.result.confirmations; + console.log( util.format("Height: %d/%d [%d%%]", h, d, 100*h/(h+d))); + } + + Block.create( blockInfo.result, function(err, inBlock) { + + // E11000 => already exists + if (err && ! err.toString().match(/E11000/)) { + return cb(err); + } + + return that.getNextBlock(blockInfo.result.nextblockhash, cb); + + }); + }); + } + + Sync.prototype.syncBlocks = function (reindex, cb) { + + var that = this; + var genesisHash = this.network.genesisBlock.hash.reverse().toString('hex'); + + 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 + ; + + + console.log('Starting at hash: ' + nextHash); + return that.getNextBlock(nextHash, cb); + }); + } + + + Sync.prototype.start = function (reindex, cb) { + + + 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:')); + + db.once('open', function callback () { + + that.syncBlocks(reindex, function(err) { + if (err) { + return cb(err); + + } + mongoose.connection.close(); + return cb(); + }); + }); + } + return Sync; +}; +module.defineClass(spec); +