Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(search): adds utils for hash test + fix search issue #52

Merged
merged 10 commits into from
Nov 13, 2019
10 changes: 2 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
sudo: false
dist: trusty
dist: xenial
language: node_js

node_js:
Expand All @@ -13,13 +13,8 @@ services:
env:
- MOZ_HEADLESS=1
addons:
apt:
sources:
- google-chrome
packages:
- docker-ce
- google-chrome-stable
firefox: latest
chrome: stable

branches:
only:
Expand All @@ -33,7 +28,6 @@ before_install:
# Use latest supported NPM in order to speedup build and support `npm ci`
- npm i -g npm@6
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

install:
- npm ci
Expand Down
2 changes: 2 additions & 0 deletions public/src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ angular.module('insight',[
'angularMoment',
'insight.system',
'insight.socket',
'insight.hash',
'insight.blocks',
'insight.transactions',
'insight.address',
Expand All @@ -27,6 +28,7 @@ angular.module('insight',[

angular.module('insight.system', []);
angular.module('insight.socket', []);
angular.module('insight.hash', []);
angular.module('insight.blocks', []);
angular.module('insight.transactions', []);
angular.module('insight.address', []);
Expand Down
9 changes: 8 additions & 1 deletion public/src/js/controllers/header.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
'use strict';

angular.module('insight.system').controller('HeaderController',
function($scope, $rootScope, $uibModal, getSocket, Global, Block) {
function($scope, $rootScope, $uibModal, getSocket, Global, Block, Status) {
$scope.global = Global;

// This allow us to do crafted logic by the network, such can be seen in BlockHash.test().
$rootScope.network = 'testnet';
Status.get({},
function(status) {
$rootScope.network = status.info && status.info.network || 'testnet';
});

$rootScope.currency = {
factor: 1,
bitstamp: 0,
Expand Down
138 changes: 82 additions & 56 deletions public/src/js/controllers/search.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,90 @@
'use strict';

angular.module('insight.search').controller('SearchController',
function($scope, $routeParams, $location, $timeout, Global, Block, Transaction, Address, BlockByHeight) {
$scope.global = Global;
$scope.loading = false;
angular.module('insight.search')
.controller('SearchController',
function ($scope, $rootScope, $routeParams, $location, $timeout, Global, Block, Transaction, Address, BlockHashValidator, TransactionHashValidator, AddressValidator, BlockByHeight) {
$scope.global = Global;
$scope.loading = false;

var _badQuery = function() {
$scope.badQuery = true;
var currentNetwork = $rootScope.network;

$timeout(function() {
$scope.badQuery = false;
}, 2000);
};
var _badQuery = function () {
$scope.badQuery = true;

var _resetSearch = function() {
$scope.q = '';
$scope.loading = false;
};
$timeout(function () {
$scope.badQuery = false;
}, 2000);
};

$scope.search = function() {
var q = $scope.q;
$scope.badQuery = false;
$scope.loading = true;
var _resetSearch = function () {
$scope.q = '';
$scope.loading = false;
};

Block.get({
blockHash: q
}, function() {
_resetSearch();
$location.path('block/' + q);
}, function() { //block not found, search on TX
Transaction.get({
txId: q
}, function() {
_resetSearch();
$location.path('tx/' + q);
}, function() { //tx not found, search on Address
Address.get({
addrStr: q
}, function() {
_resetSearch();
$location.path('address/' + q);
}, function() { // block by height not found
if (isFinite(q)) { // ensure that q is a finite number. A logical height value.
BlockByHeight.get({
blockHeight: q
}, function(hash) {
_resetSearch();
$location.path('/block/' + hash.blockHash);
}, function() { //not found, fail :(
$scope.loading = false;
_badQuery();
});
}
else {
$scope.loading = false;
_badQuery();
}
});
});
});
};
$scope.search = function () {
var q = $scope.q;
$scope.badQuery = false;
$scope.loading = true;
var isBlockHeight = isFinite(q);
var isBlockHash = BlockHashValidator.test(q, currentNetwork);
var isTransactionHash = TransactionHashValidator.test(q);
var isAddress = AddressValidator.test(q);

var badQueryLoadHandler = function () {
$scope.loading = false;
_badQuery();
};

var fetchAndRedirectTransactionSearch = function(){
return Transaction.get({
txId: q
}, function () {
_resetSearch();
$location.path('/tx/' + q);
}, badQueryLoadHandler);
};

});
var fetchAndRedirectBlockHeightSearch = function () {
return BlockByHeight.get({
blockHeight: q
}, function (hash) {
_resetSearch();
$location.path('/block/' + hash.blockHash);
}, badQueryLoadHandler);
};
var fetchAndRedirectAddressSearch = function () {
return Address.get({
addrStr: q
}, function () {
_resetSearch();
$location.path('address/' + q);
}, badQueryLoadHandler);
};
var fetchAndRedirectBlockSearch = function () {
// Block hashes are identified by expecting 10 trailing zeroes as prefix (see difficulty)
// If we are in the 1/Inf case of a txhash starting with ten zeroes, we will fallback on tx
return Block.get({
blockHash: q
}, function (res) {
if(res.status === 404){
return fetchAndRedirectTransactionSearch();
}
_resetSearch();
$location.path('/block/' + q);
}, fetchAndRedirectTransactionSearch);
};

if (isBlockHeight) {
fetchAndRedirectBlockHeightSearch();
} else if (isAddress) {
fetchAndRedirectAddressSearch();
} else if (isBlockHash) {
fetchAndRedirectBlockSearch();
} else if (isTransactionHash) {
fetchAndRedirectTransactionSearch();
} else {
badQueryLoadHandler();
}
};

});
5 changes: 3 additions & 2 deletions public/src/js/controllers/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ angular.module('insight.status').controller('StatusController',
$scope.sync = sync;
};

var socket = getSocket($scope);

var _startSocket = function () {
socket.emit('subscribe', 'sync');
socket.on('status', function(sync) {
_onSyncUpdate(sync);
});
};

var socket = getSocket($scope);

socket.on('connect', function() {
_startSocket();
});
Expand Down
15 changes: 9 additions & 6 deletions public/src/js/controllers/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,15 @@ function($scope, $rootScope, $routeParams, $location, Global, Transaction, Trans
Transaction.get({
txId: txid
}, function(tx) {
$rootScope.titleDetail = tx.txid.substring(0,7) + '...';
$rootScope.flashMessage = null;
$scope.tx = tx;
_processTX(tx);
$scope.txs.unshift(tx);
if(tx.txid){
$rootScope.titleDetail = tx.txid.substring(0,7) + '...';
}
$rootScope.flashMessage = null;
$scope.tx = tx;
_processTX(tx);
$scope.txs.unshift(tx);
}, function(e) {
// FIXME : Do we even enter here ? status 4** do not throw exceptions
if (e.status === 400) {
$rootScope.flashMessage = 'Invalid Transaction ID: ' + $routeParams.txId;
}
Expand Down Expand Up @@ -164,7 +167,7 @@ function($scope, $rootScope, $routeParams, $location, Global, Transaction, Trans
$scope.v_index = parseInt($routeParams.v_index);
$scope.itemsExpanded = true;
}

//Init without txs
$scope.txs = [];

Expand Down
46 changes: 27 additions & 19 deletions public/src/js/services/address.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
'use strict';

angular.module('insight.address').factory('Address',
function($resource) {
return $resource(window.apiPrefix + '/addr/:addrStr/?noTxList=1', {
addrStr: '@addStr'
}, {
get: {
method: 'GET',
interceptor: {
response: function (res) {
return res.data;
},
responseError: function (res) {
if (res.status === 404) {
return res;
angular.module('insight.address')
.factory('Address',
function ($resource) {
return $resource(window.apiPrefix + '/addr/:addrStr/?noTxList=1', {
addrStr: '@addStr'
}, {
get: {
method: 'GET',
interceptor: {
response: function (res) {
return res.data;
},
responseError: function (res) {
if (res.status === 404) {
return res;
}
}
}
}
}
}
});
});
});
})
.factory('AddressValidator',
function () {
return {
test: function (addressStr) {


return /^[XxYy][1-9A-Za-z][^OIl]{20,40}/.test(addressStr);
}
};
});
52 changes: 32 additions & 20 deletions public/src/js/services/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,42 @@

angular.module('insight.blocks')
.factory('Block',
function($resource) {
return $resource(window.apiPrefix + '/block/:blockHash', {
blockHash: '@blockHash'
}, {
get: {
method: 'GET',
interceptor: {
response: function (res) {
return res.data;
},
responseError: function (res) {
if (res.status === 404) {
return res;
function ($resource) {
return $resource(window.apiPrefix + '/block/:blockHash', {
blockHash: '@blockHash'
}, {
get: {
method: 'GET',
interceptor: {
response: function (res) {
return res.data;
},
responseError: function (res) {
if (res.status === 404) {
return res;
}
}
}
}
}
});
})
});
})
.factory('Blocks',
function($resource) {
function ($resource) {
return $resource(window.apiPrefix + '/blocks');
})
})
.factory('BlockHashValidator',
function (HashValidator) {
return {
test: function (blockHashStr, network) {
// Cir. 2014, difficulty implies at least 10 trailing zeroes. See https://github.com/dashevo/insight-ui/pull/52
// On testnet, we still keep it at 4 (a single micro aws achieves it)
var expectedBlockHashTrailingZeroes = (network==='testnet' || network === undefined) ? '0000' : '0000000000';
return HashValidator.test64(blockHashStr) && blockHashStr.startsWith(expectedBlockHashTrailingZeroes) ||
(HashValidator.test66(blockHashStr) && blockHashStr.startsWith('0x'+expectedBlockHashTrailingZeroes));
}
};
})
.factory('BlockByHeight',
function($resource) {
function ($resource) {
return $resource(window.apiPrefix + '/block-index/:blockHeight');
});
});
14 changes: 14 additions & 0 deletions public/src/js/services/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

angular.module('insight.hash')
.factory('HashValidator',
function () {
return {
test64: function (hashStr) {
return typeof hashStr === 'string' && /^(0x)?[0-9a-f]{64}$/i.test(hashStr);
},
test66: function (hashStr) {
return typeof hashStr === 'string' && /^(0x)?[0-9a-f]{66}$/i.test(hashStr);
}
};
});
Loading