Merge pull request #346 from Bitcoin-com/wallet/task/593

Bug - 593 - Update confirmations on cached transactions
This commit is contained in:
Brendon Duncan 2018-09-21 11:29:30 -07:00 committed by GitHub
commit 46413fa6aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 33 deletions

View file

@ -65,6 +65,9 @@ module.exports = function(grunt) {
run_android: { run_android: {
command: 'cordova run android --device', command: 'cordova run android --device',
}, },
run_android_emulator: {
command: 'cordova run android --emulator',
},
sign_android: { sign_android: {
// When the build log outputs "Built the following apk(s):", it seems to need the filename to start with "android-release". // When the build log outputs "Built the following apk(s):", it seems to need the filename to start with "android-release".
// It looks like it simply lists all apk files starting with "android-release" // It looks like it simply lists all apk files starting with "android-release"
@ -363,13 +366,14 @@ module.exports = function(grunt) {
grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']); grunt.registerTask('build-mobile-release', ['build-ios-release', 'build-android-release']);
// Build ios // Build ios
grunt.registerTask('start-ios', ['exec:build_ios_debug', 'exec:xcode']); grunt.registerTask('start-ios', ['default', 'exec:build_ios_debug', 'exec:xcode']);
grunt.registerTask('build-ios-debug', ['exec:build_ios_debug']); grunt.registerTask('build-ios-debug', ['default', 'exec:build_ios_debug']);
grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']); grunt.registerTask('build-ios-release', ['prod', 'exec:build_ios_release']);
// Build android // Build android
grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']); grunt.registerTask('start-android', ['build-android-debug', 'exec:run_android']);
grunt.registerTask('build-android-debug', ['exec:build_android_debug']); grunt.registerTask('build-android-debug', ['default', 'exec:build_android_debug']);
grunt.registerTask('start-android-emulator', ['build-android-debug', 'exec:run_android_emulator']);
grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']); grunt.registerTask('build-android-release', ['prod', 'exec:build_android_release', 'sign-android']);
grunt.registerTask('sign-android', ['exec:sign_android']); grunt.registerTask('sign-android', ['exec:sign_android']);

View file

@ -126,6 +126,7 @@
"start": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0", "start": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0",
"start:chrome": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0 --browser \"google chrome\"", "start:chrome": "npm run build:www && ionic serve --nolivereload --nogulp -s --address 0.0.0.0 --browser \"google chrome\"",
"start:android": "grunt start-android", "start:android": "grunt start-android",
"start:android-emulator": "grunt start-android",
"start:android-log": "grunt start-android && npm run log:android", "start:android-log": "grunt start-android && npm run log:android",
"start:ios": "grunt start-ios", "start:ios": "grunt start-ios",
"start:windows": "npm run build:www && npm run build:windows", "start:windows": "npm run build:www && npm run build:windows",

View file

@ -400,8 +400,8 @@ angular.module('copayApp.controllers').controller('walletDetailsController', fun
var refreshInterval; var refreshInterval;
$scope.$on("$ionicView.afterEnter", function(event, data) { $scope.$on("$ionicView.afterEnter", function onAfterEnter(event, data) {
$scope.updateAll(); $scope.updateAll(true, true);
// refreshAmountSection(); // refreshAmountSection();
refreshInterval = $interval($scope.onRefresh, 10 * 1000); refreshInterval = $interval($scope.onRefresh, 10 * 1000);
$timeout(function() { $timeout(function() {

View file

@ -85,7 +85,9 @@ angular.module('copayApp.services').factory('bitcoincomService', function(gettex
}; };
var register = function() { var register = function() {
if (!platformInfo.isAndroid) { // To comply with Google Play policies
nextStepsService.register(cashGamesItem); nextStepsService.register(cashGamesItem);
}
nextStepsService.register(newsItem); nextStepsService.register(newsItem);
nextStepsService.register(poolItem); nextStepsService.register(poolItem);
nextStepsService.register(toolsItem); nextStepsService.register(toolsItem);

View file

@ -10,7 +10,7 @@ angular.module('copayApp.services')
isoCode: 'en', isoCode: 'en',
rateCode: 'USD' rateCode: 'USD'
}, { }, {
name: 'català', name: 'Català',
isoCode: 'ca', isoCode: 'ca',
rateCode: 'EUR' rateCode: 'EUR'
},{ },{
@ -59,10 +59,6 @@ angular.module('copayApp.services')
name: 'Português', name: 'Português',
isoCode: 'pt', isoCode: 'pt',
rateCode: 'EUR' rateCode: 'EUR'
}, {
name: 'русский язык',
isoCode: 'ru',
rateCode: 'RUB'
}, { }, {
name: '한국어', name: '한국어',
isoCode: 'ko', isoCode: 'ko',

View file

@ -12,9 +12,9 @@
// How much to overlap on each end of the page, for mitigating inconsistent sort order. // How much to overlap on each end of the page, for mitigating inconsistent sort order.
var PAGE_OVERLAP_FRACTION = 0.2; var PAGE_OVERLAP_FRACTION = 0.2;
var PAGE_OVERLAP = Math.floor(PAGE_SIZE * PAGE_OVERLAP_FRACTION); var PAGE_OVERLAP = Math.floor(PAGE_SIZE * PAGE_OVERLAP_FRACTION);
// The amount of transactions in the new overlapping resultset that we already know about. // The fraction of transactions in the new overlapping resultset that we already know about.
// If we know about at least this many, then there are probably no gaps. // If we know about at least this many, then there are probably no gaps.
var MIN_KNOWN_TX_OVERLAP = Math.floor(PAGE_OVERLAP * 0.5); var MIN_KNOWN_TX_OVERLAP_FRACTION = 0.5;
var SAFE_CONFIRMATIONS = 6; var SAFE_CONFIRMATIONS = 6;
@ -27,26 +27,34 @@
function addEarlyTransactions(walletId, cachedTxs, newTxs) { function addEarlyTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIds = {}; var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx){ cachedTxs.forEach(function forCachedTx(tx){
cachedTxIds[tx.txid] = true; cachedTxIndexFromId[tx.txid] = true;
}); });
var confirmationsUpdated = false;
var someTransactionsWereNew = false; var someTransactionsWereNew = false;
var overlappingTxsCount = 0; var overlappingTxsCount = 0;
newTxs.forEach(function forNewTx(tx){ newTxs.forEach(function forNewTx(tx){
if (cachedTxIds[tx.txid]) { if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
overlappingTxsCount++;
} else {
someTransactionsWereNew = true; someTransactionsWereNew = true;
cachedTxs.push(tx); cachedTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
} }
}); });
if (overlappingTxsCount >= MIN_KNOWN_TX_OVERLAP) { // We are good var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP);
console.log('overlappingTxFraction:', overlappingTxFraction);
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
if (someTransactionsWereNew) { if (someTransactionsWereNew) {
saveTxHistory(walletId, cachedTxs); saveTxHistory(walletId, cachedTxs);
} else if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
} else if (overlappingTxsCount === newTxs.length) { } else if (overlappingTxsCount === newTxs.length) {
allTransactionsFetched = true; allTransactionsFetched = true;
} }
@ -62,30 +70,38 @@
} }
function addLatestTransactions(walletId, cachedTxs, newTxs) { function addLatestTransactions(walletId, cachedTxs, newTxs) {
var cachedTxIds = {}; var cachedTxIndexFromId = {};
cachedTxs.forEach(function forCachedTx(tx){ cachedTxs.forEach(function forCachedTx(tx, txIndex){
cachedTxIds[tx.txid] = true; cachedTxIndexFromId[tx.txid] = txIndex;
}); });
var someTransactionsWereNew = false; var someTransactionsWereNew = false;
var confirmationsUpdated = false;
var overlappingTxsCount = 0; var overlappingTxsCount = 0;
var uniqueNewTxs = []; var uniqueNewTxs = [];
newTxs.forEach(function forNewTx(tx){ newTxs.forEach(function forNewTx(tx){
if (cachedTxIds[tx.txid]) { if (typeof cachedTxIndexFromId[tx.txid] === "undefined") {
overlappingTxsCount++;
} else {
someTransactionsWereNew = true; someTransactionsWereNew = true;
uniqueNewTxs.push(tx); uniqueNewTxs.push(tx);
} else {
var txUpdated = updateCachedTx(cachedTxs, cachedTxIndexFromId, tx);
confirmationsUpdated = confirmationsUpdated || txUpdated;
overlappingTxsCount++;
} }
}); });
if (overlappingTxsCount >= MIN_KNOWN_TX_OVERLAP) { // We are good var overlappingTxFraction = overlappingTxsCount / Math.min(cachedTxs.length, PAGE_OVERLAP);
if (overlappingTxFraction >= MIN_KNOWN_TX_OVERLAP_FRACTION) { // We are good
if (someTransactionsWereNew) { if (someTransactionsWereNew) {
var allTxs = uniqueNewTxs.concat(cachedTxs); var allTxs = uniqueNewTxs.concat(cachedTxs);
saveTxHistory(walletId, allTxs); saveTxHistory(walletId, allTxs);
return allTxs; return allTxs;
} else { } else {
if (confirmationsUpdated) {
saveTxHistory(walletId, cachedTxs);
}
return cachedTxs; return cachedTxs;
} }
} else { } else {
@ -99,6 +115,8 @@
// Only clear the cache once we have received new transactions from the server. // Only clear the cache once we have received new transactions from the server.
/** /**
* @param wallet
* @param start
* @param {function(err, txs)} cb - transactions is always an array, may be empty * @param {function(err, txs)} cb - transactions is always an array, may be empty
*/ */
function fetchTxHistoryByPage(wallet, start, cb) { function fetchTxHistoryByPage(wallet, start, cb) {
@ -182,7 +200,7 @@
}); });
return processedTxs; return processedTxs;
}; }
function saveTxHistory(walletId, processedTxs) { function saveTxHistory(walletId, processedTxs) {
storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){ storageService.setTxHistory(processedTxs, walletId, function onSetTxHistory(error){
@ -192,9 +210,25 @@
}); });
} }
/**
* Returns true if the cached tx was updated
* @param {*} cachedTxs
* @param {*} cachedTxIndexFromId - Indices for cachedTxs, based on txid
* @param {*} tx - The most recent tx info
*/
function updateCachedTx(cachedTxs, cachedTxIndexFromId, tx) {
var updated = false;
var txIndex = cachedTxIndexFromId[tx.txid];
var cachedTx = cachedTxs[txIndex];
if (cachedTx.confirmations < SAFE_CONFIRMATIONS && tx.confirmations > cachedTx.confirmations) {
cachedTxs[txIndex].confirmations = tx.confirmations;
updated = true;
}
return updated;
}
function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) { function updateLocalTxHistoryByPage(wallet, getLatest, flushCacheOnNew, cb) {
if (flushCacheOnNew) { if (flushCacheOnNew) {
fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){ fetchTxHistoryByPage(wallet, 0, function onFetchTxHistory(err, txs){
if (err) { if (err) {
@ -235,10 +269,5 @@
}); });
} }
} }
} }
})(); })();