Skip to content

Commit

Permalink
Merge pull request #52 from dashevo/fix/search
Browse files Browse the repository at this point in the history
fix(search): adds utils for hash test + fix search issue
  • Loading branch information
Alex-Werner authored Nov 13, 2019
2 parents 34c4628 + 1457623 commit f02ef76
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 140 deletions.
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

0 comments on commit f02ef76

Please sign in to comment.