Merge pull request #108 from maraoz/feature/realtime-sync-info
Feature/realtime sync info
This commit is contained in:
commit
590acff915
|
@ -27,5 +27,5 @@ module.exports.broadcast_address_tx = function(address, tx) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.broadcastSyncInfo = function(syncInfo) {
|
module.exports.broadcastSyncInfo = function(syncInfo) {
|
||||||
ios.sockets.emit('sync', syncInfo);
|
ios.sockets.in('sync').emit('status', syncInfo);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
|
|
||||||
function spec() {
|
function spec() {
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var RpcClient = require('bitcore/RpcClient').class();
|
var RpcClient = require('bitcore/RpcClient').class();
|
||||||
|
@ -21,7 +20,6 @@ function spec() {
|
||||||
this.genesis = genesisHashReversed.reverse().toString('hex');
|
this.genesis = genesisHashReversed.reverse().toString('hex');
|
||||||
this.sync = new Sync(opts);
|
this.sync = new Sync(opts);
|
||||||
|
|
||||||
|
|
||||||
//available status: new / syncing / finished / aborted
|
//available status: new / syncing / finished / aborted
|
||||||
this.status = 'new';
|
this.status = 'new';
|
||||||
this.syncInfo = {};
|
this.syncInfo = {};
|
||||||
|
@ -31,8 +29,6 @@ function spec() {
|
||||||
var args = [];
|
var args = [];
|
||||||
Array.prototype.push.apply(args, arguments);
|
Array.prototype.push.apply(args, arguments);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
args.unshift('[historic_sync]');
|
args.unshift('[historic_sync]');
|
||||||
/*jshint validthis:true */
|
/*jshint validthis:true */
|
||||||
console.log.apply(this, args);
|
console.log.apply(this, args);
|
||||||
|
@ -48,36 +44,40 @@ function spec() {
|
||||||
this.sync.close();
|
this.sync.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.showProgress = function() {
|
HistoricSync.prototype.showProgress = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var i = self.syncInfo;
|
var i = self.syncInfo;
|
||||||
var per = parseInt(100 * i.syncedBlocks / i.blocksToSync);
|
var per = parseInt(100 * i.syncedBlocks / i.blocksToSync);
|
||||||
p(util.format('status: %d/%d [%d%%]', i.syncedBlocks, i.blocksToSync, per));
|
p(util.format('status: %d/%d [%d%%]', i.syncedBlocks, i.blocksToSync, per));
|
||||||
if (self.opts.broadcast) {
|
if (self.opts.shouldBroadcast) {
|
||||||
sockets.broadcastSyncInfo(self.syncInfo);
|
sockets.broadcastSyncInfo(self.syncInfo);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
HistoricSync.prototype.getPrevNextBlock = function(blockHash, blockEnd, opts, cb) {
|
HistoricSync.prototype.getPrevNextBlock = function(blockHash, blockEnd, opts, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// recursion end.
|
// recursion end.
|
||||||
if (!blockHash) return cb();
|
if (!blockHash) return cb();
|
||||||
|
|
||||||
var existed = 0;
|
var existed = false;
|
||||||
var blockInfo;
|
var blockInfo;
|
||||||
var blockObj;
|
var blockObj;
|
||||||
|
|
||||||
async.series([
|
async.series([
|
||||||
// Already got it?
|
// Already got it?
|
||||||
function(c) {
|
function(c) {
|
||||||
Block.findOne({hash:blockHash}, function(err,block){
|
Block.findOne({
|
||||||
if (err) { p(err); return c(err); }
|
hash: blockHash
|
||||||
|
},
|
||||||
|
function(err, block) {
|
||||||
|
if (err) {
|
||||||
|
p(err);
|
||||||
|
return c(err);
|
||||||
|
}
|
||||||
if (block) {
|
if (block) {
|
||||||
existed =1;
|
existed = true;
|
||||||
blockObj = block;
|
blockObj = block;
|
||||||
}
|
}
|
||||||
return c();
|
return c();
|
||||||
|
@ -85,10 +85,15 @@ function spec() {
|
||||||
},
|
},
|
||||||
//show some (inacurate) status
|
//show some (inacurate) status
|
||||||
function(c) {
|
function(c) {
|
||||||
|
if (!self.step) {
|
||||||
var step = parseInt(self.syncInfo.blocksToSync / 100);
|
var step = parseInt(self.syncInfo.blocksToSync / 100);
|
||||||
if (step < 10) step = 10;
|
if (self.opts.progressStep) {
|
||||||
|
step = self.opts.progressStep;
|
||||||
if (self.syncInfo.syncedBlocks % step === 1) {
|
}
|
||||||
|
if (step < 2) step = 2;
|
||||||
|
self.step = step;
|
||||||
|
}
|
||||||
|
if (self.syncInfo.syncedBlocks % self.step === 1) {
|
||||||
self.showProgress();
|
self.showProgress();
|
||||||
}
|
}
|
||||||
return c();
|
return c();
|
||||||
|
@ -98,7 +103,6 @@ function spec() {
|
||||||
|
|
||||||
// TODO: if we store prev/next, no need to go to RPC
|
// TODO: if we store prev/next, no need to go to RPC
|
||||||
// if (blockObj && blockObj.nextBlockHash) return c();
|
// if (blockObj && blockObj.nextBlockHash) return c();
|
||||||
|
|
||||||
self.rpc.getBlock(blockHash, function(err, ret) {
|
self.rpc.getBlock(blockHash, function(err, ret) {
|
||||||
if (err) return c(err);
|
if (err) return c(err);
|
||||||
|
|
||||||
|
@ -127,8 +131,7 @@ function spec() {
|
||||||
return c();
|
return c();
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
],
|
], function(err) {
|
||||||
function (err){
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncInfo.syncedBlocks);
|
self.err = util.format('ERROR: @%s: %s [count: syncedBlocks: %d]', blockHash, err, self.syncInfo.syncedBlocks);
|
||||||
|
@ -162,7 +165,6 @@ function spec() {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Continue
|
// Continue
|
||||||
if (blockInfo && blockInfo.result) {
|
if (blockInfo && blockInfo.result) {
|
||||||
if (!existed) self.syncInfo.syncedBlocks++;
|
if (!existed) self.syncInfo.syncedBlocks++;
|
||||||
|
@ -170,8 +172,7 @@ function spec() {
|
||||||
return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb);
|
return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.next && blockInfo.result.nextblockhash)
|
if (opts.next && blockInfo.result.nextblockhash) return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb);
|
||||||
return self.getPrevNextBlock(blockInfo.result.nextblockhash, blockEnd, opts, cb);
|
|
||||||
}
|
}
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
|
@ -225,7 +226,10 @@ function spec() {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// should be isOrphan = true or null to be more accurate.
|
// should be isOrphan = true or null to be more accurate.
|
||||||
Block.count({ isOrphan: null}, function(err, count) {
|
Block.count({
|
||||||
|
isOrphan: null
|
||||||
|
},
|
||||||
|
function(err, count) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
self.syncInfo.blocksToSync = blockChainHeight - count;
|
self.syncInfo.blocksToSync = blockChainHeight - count;
|
||||||
|
@ -234,9 +238,7 @@ function spec() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
], function(err) {
|
||||||
function(err) {
|
|
||||||
|
|
||||||
|
|
||||||
var start, end;
|
var start, end;
|
||||||
function sync() {
|
function sync() {
|
||||||
|
@ -271,15 +273,17 @@ function spec() {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
p('Retrying in %d secs', retry_secs);
|
p('Retrying in %d secs', retry_secs);
|
||||||
sync();
|
sync();
|
||||||
}, retry_secs * 1000);
|
},
|
||||||
|
retry_secs * 1000);
|
||||||
}
|
}
|
||||||
else
|
else return next(err);
|
||||||
return next(err);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
self.syncInfo = util._extend(self.syncInfo, { error: err.message });
|
self.syncInfo = util._extend(self.syncInfo, {
|
||||||
|
error: err.message
|
||||||
|
});
|
||||||
return next(err, 0);
|
return next(err, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -292,11 +296,13 @@ function spec() {
|
||||||
HistoricSync.prototype.smart_import = function(next) {
|
HistoricSync.prototype.smart_import = function(next) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
Block.findOne({hash:self.genesis}, function(err, b){
|
Block.findOne({
|
||||||
|
hash: self.genesis
|
||||||
|
},
|
||||||
|
function(err, b) {
|
||||||
|
|
||||||
if (err) return next(err);
|
if (err) return next(err);
|
||||||
|
|
||||||
|
|
||||||
if (!b) {
|
if (!b) {
|
||||||
p('Could not find Genesis block. Running FULL SYNC');
|
p('Could not find Genesis block. Running FULL SYNC');
|
||||||
}
|
}
|
||||||
|
@ -305,7 +311,7 @@ function spec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts = {
|
var opts = {
|
||||||
reverse: 1,
|
reverse: true,
|
||||||
upToExisting: b ? true: false,
|
upToExisting: b ? true: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -313,7 +319,6 @@ function spec() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return HistoricSync;
|
return HistoricSync;
|
||||||
}
|
}
|
||||||
module.defineClass(spec);
|
module.defineClass(spec);
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('insight.status').controller('StatusController',
|
angular.module('insight.status').controller('StatusController',
|
||||||
function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync) {
|
function($scope, $routeParams, $location, $rootScope, Global, Status, Sync, get_socket) {
|
||||||
$scope.global = Global;
|
$scope.global = Global;
|
||||||
|
|
||||||
$scope.getStatus = function(q) {
|
$scope.getStatus = function(q) {
|
||||||
Status.get({
|
Status.get({
|
||||||
q: 'get' + q
|
q: 'get' + q
|
||||||
}, function(d) {
|
},
|
||||||
|
function(d) {
|
||||||
$rootScope.infoError = null;
|
$rootScope.infoError = null;
|
||||||
angular.extend($scope, d);
|
angular.extend($scope, d);
|
||||||
}, function(e) {
|
},
|
||||||
|
function(e) {
|
||||||
if (e.status === 503) {
|
if (e.status === 503) {
|
||||||
$rootScope.infoError = 'Backend Error. ' + e.data;
|
$rootScope.infoError = 'Backend Error. ' + e.data;
|
||||||
}
|
}
|
||||||
|
@ -20,24 +22,36 @@ angular.module('insight.status').controller('StatusController',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.getSync = function() {
|
var on_sync_update = function(sync) {
|
||||||
Sync.get({}, function(sync) {
|
|
||||||
$rootScope.syncError = null;
|
|
||||||
|
|
||||||
if (sync.blocksToSync > sync.syncedBlocks) {
|
if (sync.blocksToSync > sync.syncedBlocks) {
|
||||||
sync.message = 'Blocks to sync: ' + (sync.blocksToSync - sync.syncedBlocks);
|
var p = parseInt(100*(sync.syncedBlocks) / sync.blocksToSync);
|
||||||
sync.tooltip = 'Skipped blocks:' + sync.skipped_blocks;
|
var delta = sync.blocksToSync - sync.syncedBlocks;
|
||||||
}
|
sync.message = 'Sync ' + p + '% ['+delta+' blocks remaining]';
|
||||||
else {
|
sync.style = 'warn';
|
||||||
|
} else {
|
||||||
sync.message = 'On sync';
|
sync.message = 'On sync';
|
||||||
sync.tooltip = '';
|
sync.style = 'success';
|
||||||
}
|
}
|
||||||
|
sync.tooltip = 'Synced blocks: '+sync.syncedBlocks;
|
||||||
|
|
||||||
$scope.sync = sync;
|
$scope.sync = sync;
|
||||||
}, function(e) {
|
};
|
||||||
|
|
||||||
|
$scope.getSync = function() {
|
||||||
|
Sync.get({},
|
||||||
|
function(sync) {
|
||||||
|
$rootScope.syncError = null;
|
||||||
|
on_sync_update(sync);
|
||||||
|
},
|
||||||
|
function(e) {
|
||||||
$rootScope.syncError = 'Could not get sync information' + e;
|
$rootScope.syncError = 'Could not get sync information' + e;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var socket = get_socket($scope);
|
||||||
|
socket.emit('subscribe', 'sync');
|
||||||
|
socket.on('status', function(sync) {
|
||||||
|
on_sync_update(sync);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<div class="status" data-ng-controller="StatusController">
|
<div class="status" data-ng-controller="StatusController">
|
||||||
<span data-ng-init="getSync()">
|
<span data-ng-init="getSync()">
|
||||||
<span class="small" tooltip="{{sync.tooltip}}" tooltip-placement="down">
|
<span class="small" tooltip="{{sync.tooltip}}" tooltip-placement="down">
|
||||||
<i><strong> {{sync.message}} </strong></i>
|
<i class="{{sync.style}}"><strong> {{sync.message}} </strong></i>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span data-ng-init="getStatus('Info')">
|
<span data-ng-init="getStatus('Info')">
|
||||||
|
|
|
@ -60,6 +60,7 @@ if (!config.disableHistoricSync) {
|
||||||
historicSync.init({
|
historicSync.init({
|
||||||
skipDbConnection: true,
|
skipDbConnection: true,
|
||||||
shouldBroadcast: true,
|
shouldBroadcast: true,
|
||||||
|
progressStep: 2,
|
||||||
networkName: config.network
|
networkName: config.network
|
||||||
}, function() {
|
}, function() {
|
||||||
historicSync.smart_import(function(err){
|
historicSync.smart_import(function(err){
|
||||||
|
|
Loading…
Reference in New Issue