diff --git a/app/controllers/addresses.js b/app/controllers/addresses.js
index e13000c..30671ee 100644
--- a/app/controllers/addresses.js
+++ b/app/controllers/addresses.js
@@ -4,30 +4,32 @@
* Module dependencies.
*/
-var Address = require('../models/Address');
+var Address = require('../models/Address'),
+ common = require('./common');
-/**
- * Find block by hash ...
- */
exports.address = function(req, res, next, addr) {
- var a = Address.new(addr);
+
+
+ var a;
+ try {
+ a = Address.new(addr);
+ } catch (e) {
+ return common.handleErrors({message: 'Invalid address:' + e.message, code: 1}, res, next);
+ }
a.update(function(err) {
- if (err && !a.totalReceivedSat) {
- console.log(err);
- res.status(404).send('Invalid address');
- return next();
- }
-
- req.address = a;
- return next();
- });
+ if (err)
+ return common.handleErrors(err, res);
+ else {
+ req.address = a;
+ return next();
+ }
+ });
};
/**
- * Show block
*/
exports.show = function(req, res) {
if (req.address) {
diff --git a/app/controllers/blocks.js b/app/controllers/blocks.js
index a21d52e..37324a0 100644
--- a/app/controllers/blocks.js
+++ b/app/controllers/blocks.js
@@ -4,7 +4,8 @@
* Module dependencies.
*/
var mongoose = require('mongoose'),
- Block = mongoose.model('Block');
+ Block = mongoose.model('Block'),
+ common = require('./common');
/**
@@ -12,14 +13,12 @@ var mongoose = require('mongoose'),
*/
exports.block = function(req, res, next, hash) {
Block.fromHashWithInfo(hash, function(err, block) {
- if (err && !block) {
- console.log(err);
- res.status(404).send('Not found');
+ if (err || ! block)
+ return common.handleErrors(err, res, next);
+ else {
+ req.block = block.info;
return next();
}
-
- req.block = block.info;
- return next();
});
};
diff --git a/app/controllers/common.js b/app/controllers/common.js
new file mode 100644
index 0000000..b44756b
--- /dev/null
+++ b/app/controllers/common.js
@@ -0,0 +1,16 @@
+'use strict';
+
+
+exports.handleErrors = function (err, res) {
+ if (err) {
+ if (err.code) {
+ res.status(400).send(err.message + '. Code:' + err.code);
+ }
+ else {
+ res.status(503).send(err.message);
+ }
+ }
+ else {
+ res.status(404).send('Not found');
+ }
+};
diff --git a/app/controllers/socket.js b/app/controllers/socket.js
index f6e9e92..acfa2c9 100644
--- a/app/controllers/socket.js
+++ b/app/controllers/socket.js
@@ -27,5 +27,5 @@ module.exports.broadcast_address_tx = function(address, tx) {
};
module.exports.broadcastSyncInfo = function(syncInfo) {
- ios.sockets.emit('status', syncInfo);
+ ios.sockets.emit('sync', syncInfo);
};
diff --git a/app/controllers/status.js b/app/controllers/status.js
index 6652359..1874605 100644
--- a/app/controllers/status.js
+++ b/app/controllers/status.js
@@ -4,7 +4,8 @@
* Module dependencies.
*/
-var Status = require('../models/Status');
+var Status = require('../models/Status'),
+ common = require('./common');
/**
* Status
@@ -19,8 +20,11 @@ exports.show = function(req, res, next) {
var statusObject = Status.new();
var returnJsonp = function (err) {
- if(err) return next(err);
- res.jsonp(statusObject);
+ if (err || ! statusObject)
+ return common.handleErrors(err, res);
+ else {
+ res.jsonp(statusObject);
+ }
};
switch(option) {
diff --git a/app/controllers/transactions.js b/app/controllers/transactions.js
index 7276db4..5676790 100644
--- a/app/controllers/transactions.js
+++ b/app/controllers/transactions.js
@@ -7,6 +7,7 @@ var Transaction = require('../models/Transaction');
var Block = require('../models/Block');
var Address = require('../models/Address');
var async = require('async');
+var common = require('./common');
/**
@@ -14,15 +15,12 @@ var async = require('async');
*/
exports.transaction = function(req, res, next, txid) {
Transaction.fromIdWithInfo(txid, function(err, tx) {
- if (err) {
- console.log(err);
- res.status(404).send('Not found');
+ if (err || ! tx)
+ return common.handleErrors(err, res);
+ else {
+ req.transaction = tx.info;
return next();
}
-
- if (!tx) return next(new Error('Failed to load TX ' + txid));
- req.transaction = tx.info;
- next();
});
};
diff --git a/app/models/Address.js b/app/models/Address.js
index 05d1a78..e054ff1 100644
--- a/app/models/Address.js
+++ b/app/models/Address.js
@@ -19,11 +19,8 @@ function spec() {
this.transactions = [];
var a = new BitcoreAddress(addrStr);
- try {
- a.validate();
- this.addrStr = addrStr;
- } catch(e){
- }
+ a.validate();
+ this.addrStr = addrStr;
Object.defineProperty(this, 'totalSent', {
@@ -58,11 +55,6 @@ function spec() {
}
Address.prototype.update = function(next) {
-
- if (! this.addrStr) {
- return next(new Error('Invalid or undefined address string'));
- }
-
var that = this;
async.series([
// TODO TXout!
diff --git a/app/models/Block.js b/app/models/Block.js
index e4d84d3..3f4bcbc 100644
--- a/app/models/Block.js
+++ b/app/models/Block.js
@@ -81,16 +81,33 @@ BlockSchema.statics.fromHash = function(hash, cb) {
BlockSchema.statics.fromHashWithInfo = function(hash, cb) {
+ var That = this;
+
this.fromHash(hash, function(err, block) {
if (err) return cb(err);
- if (!block) { return cb(new Error('Block not found')); }
- block.getInfo(function(err) { return cb(err,block); } );
+ if (!block) {
+ // No in mongo...but maybe in bitcoind... lets query it
+ block = new That();
+
+ block.hash = hash;
+ block.getInfo(function(err, blockInfo) {
+ if (err) return cb(err);
+ if (!blockInfo) return cb();
+
+ block.save(function(err) {
+ return cb(err,block);
+ });
+ });
+ }
+ else {
+ block.getInfo(function(err) {
+ return cb(err,block);
+ });
+ }
});
};
-
-
// TODO: Can we store the rpc instance in the Block object?
BlockSchema.methods.getInfo = function (next) {
@@ -98,6 +115,9 @@ BlockSchema.methods.getInfo = function (next) {
var rpc = new RpcClient(config.bitcoind);
rpc.getBlock(this.hash, function(err, blockInfo) {
+ // Not found?
+ if (err && err.code === -5) return next();
+
if (err) return next(err);
/*
diff --git a/app/models/Status.js b/app/models/Status.js
index 321e227..517b51c 100644
--- a/app/models/Status.js
+++ b/app/models/Status.js
@@ -9,11 +9,6 @@ function spec() {
var rpc = new RpcClient(config.bitcoind);
function Status() {
- this.info = {};
- this.difficulty = {};
- this.txoutsetinfo = {};
- this.bestblockhash = {};
- this.lastblockhash = {};
}
Status.prototype.getInfo = function(next) {
diff --git a/app/models/Transaction.js b/app/models/Transaction.js
index b4f67f2..5e418ad 100644
--- a/app/models/Transaction.js
+++ b/app/models/Transaction.js
@@ -74,8 +74,8 @@ TransactionSchema.statics.fromIdWithInfo = function(txid, cb) {
tx.txid = txid;
tx.fillInfo(function(err, txInfo) {
- if (!txInfo)
- return cb(new Error('TX not found'));
+ if (err) return cb(err);
+ if (!txInfo) return cb();
tx.save(function(err) {
return cb(err,tx);
@@ -251,6 +251,10 @@ TransactionSchema.statics.queryInfo = function(txid, cb) {
var rpc = new RpcClient(config.bitcoind);
rpc.getRawTransaction(txid, 1, function(err, txInfo) {
+
+ // Not found?
+ if (err && err.code === -5) return cb();
+
if (err) return cb(err);
var info = txInfo.result;
diff --git a/lib/HistoricSync.js b/lib/HistoricSync.js
index f9d3d0a..b33b4bd 100644
--- a/lib/HistoricSync.js
+++ b/lib/HistoricSync.js
@@ -142,13 +142,17 @@ function spec() {
}
if (opts.upToExisting && existed ) {
- if (self.syncInfo.blocksToSync <= self.syncInfo.syncedBlocks) {
+ var diff = self.syncInfo.blocksToSync - self.syncInfo.syncedBlocks;
+ if (diff <= 0) {
self.status = 'finished';
p('DONE. Found existing block: ', blockHash);
return cb(err);
}
else {
- p('WARN found target block\n\tbut blockChain Height is still higher that ours. Previous light sync must be interrupted.\n\tWill keep syncing.', self.syncInfo.syncedBlocks);
+ self.syncInfo.skipped_blocks = self.syncInfo.skipped_blocks || 1;
+ if ((self.syncInfo.skipped_blocks++ % 1000) === 1 ) {
+ p('WARN found target block\n\tbut blockChain Height is still higher that ours. Previous light sync must be interrupted.\n\tWill keep syncing.', self.syncInfo.syncedBlocks, self.syncInfo.blocksToSync, self.syncInfo.skipped_blocks);
+ }
}
}
@@ -161,7 +165,7 @@ function spec() {
// Continue
if (blockInfo && blockInfo.result) {
- self.syncInfo.syncedBlocks++;
+ if (! existed) self.syncInfo.syncedBlocks++;
if (opts.prev && blockInfo.result.previousblockhash) {
return self.getPrevNextBlock(blockInfo.result.previousblockhash, blockEnd, opts, cb);
}
diff --git a/public/js/controllers/address.js b/public/js/controllers/address.js
index 6276230..664c2ba 100644
--- a/public/js/controllers/address.js
+++ b/public/js/controllers/address.js
@@ -16,8 +16,16 @@ angular.module('insight.address').controller('AddressController',
addrStr: $routeParams.addrStr
}, function(address) {
$scope.address = address;
- }, function() {
- $rootScope.flashMessage = 'Address Not Found';
+ }, function(e) {
+ if (e.status === 400) {
+ $rootScope.flashMessage = 'Invalid Address: ' + $routeParams.addrStr;
+ }
+ else if (e.status === 503) {
+ $rootScope.flashMessage = 'Backend Error. ' + e.data;
+ }
+ else {
+ $rootScope.flashMessage = 'Address Not Found';
+ }
$location.path('/');
});
};
diff --git a/public/js/controllers/blocks.js b/public/js/controllers/blocks.js
index b398ef3..e300299 100644
--- a/public/js/controllers/blocks.js
+++ b/public/js/controllers/blocks.js
@@ -17,8 +17,16 @@ angular.module('insight.blocks').controller('BlocksController', ['$scope', '$roo
blockHash: $routeParams.blockHash
}, function(block) {
$scope.block = block;
- }, function() {
- $rootScope.flashMessage = 'Block Not Found';
+ }, function(e) {
+ if (e.status === 400) {
+ $rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId;
+ }
+ else if (e.status === 503) {
+ $rootScope.flashMessage = 'Backend Error. ' + e.data;
+ }
+ else {
+ $rootScope.flashMessage = 'Block Not Found';
+ }
$location.path('/');
});
};
diff --git a/public/js/controllers/status.js b/public/js/controllers/status.js
index 8b5b538..8fa2f24 100644
--- a/public/js/controllers/status.js
+++ b/public/js/controllers/status.js
@@ -1,30 +1,31 @@
'use strict';
-angular.module('insight.status').controller('StatusController', ['$scope', '$routeParams', '$location', 'Global', 'Status', function ($scope, $routeParams, $location, Global, Status) {
+angular.module('insight.status').controller('StatusController', ['$scope', '$routeParams', '$location', '$rootScope', 'Global', 'Status', 'Sync', function ($scope, $routeParams, $location, $rootScope, Global, Status, Sync) {
$scope.global = Global;
- $scope.getData = function(q) {
+ $scope.getStatus = function(q) {
Status.get({
- q: q
+ q: 'get' + q
}, function(d) {
- if (q === 'getInfo') {
- $scope.info = d.info;
+ $rootScope.infoError = null;
+ angular.extend($scope, d);
+ }, function(e) {
+ if (e.status === 503) {
+ $rootScope.infoError = 'Backend Error. ' + e.data;
}
- if (q === 'getDifficulty') {
- $scope.difficulty = d.difficulty;
+ else {
+ $rootScope.infoError = 'Unknown error:' + e.data;
}
- if (q === 'getTxOutSetInfo') {
- $scope.txoutsetinfo = d.txoutsetinfo;
- }
- if (q === 'getBestBlockHash') {
- $scope.bestblockhash = d.bestblockhash;
- }
- if (q === 'getLastBlockHash') {
- $scope.lastblockhash = d.lastblockhash;
- }
-
});
};
+ $scope.getSync = function() {
+ Sync.get({}, function(sync) {
+ $rootScope.syncError = null;
+ $scope.sync = sync;
+ }, function(e) {
+ $rootScope.syncError = 'Could not get sync information' + e;
+ });
+ };
}]);
diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js
index 0658c5c..132881b 100644
--- a/public/js/controllers/transactions.js
+++ b/public/js/controllers/transactions.js
@@ -22,10 +22,23 @@ angular.module('insight.transactions').controller('transactionsController',
txId: txid
}, function(tx) {
$scope.tx = tx;
+<<<<<<< HEAD
console.log(console.log(tx));
$scope.txs.push(tx);
}, function() {
$rootScope.flashMessage = 'Transaction Not Found';
+=======
+ }, function(e) {
+ if (e.status === 400) {
+ $rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId;
+ }
+ else if (e.status === 503) {
+ $rootScope.flashMessage = 'Backend Error. ' + e.data;
+ }
+ else {
+ $rootScope.flashMessage = 'Transaction Not Found';
+ }
+>>>>>>> matiu/feature/11showsyncstatus
$location.path('/');
});
};
diff --git a/public/js/services/status.js b/public/js/services/status.js
index f911c33..67d7004 100644
--- a/public/js/services/status.js
+++ b/public/js/services/status.js
@@ -6,3 +6,7 @@ angular.module('insight.status').factory('Status', ['$resource', function($resou
});
}]);
+angular.module('insight.status').factory('Sync', ['$resource', function($resource) {
+ return $resource('/api/sync');
+}]);
+
diff --git a/public/views/status.html b/public/views/status.html
index 9009f92..7195119 100644
--- a/public/views/status.html
+++ b/public/views/status.html
@@ -7,11 +7,12 @@
getInfo
-
+
-
- | Loading... |
-
+
+ | Loading...
+ |
+ | {{infoError}}
|
| Version |
{{info.version}} |
@@ -65,19 +66,72 @@
{{info.paytxfee}} |
- | errors |
- {{info.errors}} |
+ infoErrors |
+ {{info.infoErrors}} |
-
getTxOutSetInfo
-
+ sync status
+
-
+
+ | {{ syncError }}
+ |
+ | {{ sync.err }}
+ |
+
+ | Sync Progress |
+ {{(100 * sync.syncedBlocks/sync.blocksToSync)| number:2}}%
+ |
+
+ | blocksToSync |
+ {{sync.blocksToSync}} |
+
+
+ | syncedBlocks |
+ {{sync.syncedBlocks}} |
+
+
+ | start |
+ {{sync.start}}
+ (genesisBlock)
+ |
+
+
+ | end |
+ {{sync.end}}
+ (genesisBlock)
+ |
+
+
+ | Sync Type |
+
+
+ - Stops at existing block
+
-
+ scanningBackward
+ scanningForward
+
+ |
+
+
+
+
+
+
+
+
+ getTxOutSetInfo
+
+
+
| Loading... |
+
+ | {{infoError}} |
+
| Height |
{{txoutsetinfo.height}} |
@@ -114,11 +168,15 @@
getDifficulty
-
+
-
+
| Loading... |
+
+ | {{infoError}} |
+
+
| Difficulty |
{{difficulty}} |
@@ -128,12 +186,16 @@
getLastBlockHash
-
+
-
- | Loading... |
+
+ | Loading... |
+
+
+ | {{infoError}} |
+ | Last block hash |
{{lastblockhash}} |