diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js index 8c19c2e9b83cef421fc88db6535970894ea19f2b..2ba2adb012cb62ae0adc7d2ac83664ed4f259f91 100644 --- a/www/js/services/bma-services.js +++ b/www/js/services/bma-services.js @@ -246,7 +246,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. if (software === 'duniter' && json.duniter.version && true) { isCompatible = csHttp.version.isCompatible(csSettings.data.minVersion, json.duniter.version); } - // TODO: check other software (DURS, Juniter, etc.) + // TODO: check version of other software (DURS, Juniter, etc.) else { console.debug('[BMA] Unknown node software [{0} v{1}]: could not check compatibility.'.format(software || '?', json.duniter.version || '?')); } @@ -424,8 +424,8 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. }, requirements: function(params, withCache) { // No cache by default - if (withCache !== true) return exports.raw.requirementsNoCache(params); - return exports.raw.requirementsWithCache(params); + if (withCache !== true) return exports.raw.wot.requirements(params); + return exports.raw.wot.requirementsWithCache(params); }, add: post('/wot/add'), certify: post('/wot/certify'), @@ -449,9 +449,27 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. sources: get('/tx/sources/:pubkey', csHttp.cache.SHORT), process: post('/tx/process'), history: { - all: get('/tx/history/:pubkey'), - times: get('/tx/history/:pubkey/times/:from/:to', csHttp.cache.LONG), - timesNoCache: get('/tx/history/:pubkey/times/:from/:to'), + all: function(params) { + return exports.raw.tx.history.all(params) + .then(res => { + res.history = res.history ||Â {}; + // Clean sending and pendings, because already returned by tx/history/:pubkey/pending + res.history.sending = []; + res.history.pendings = []; + return res; + }); + }, + times: function(params, withCache) { + // No cache by default + return ((withCache !== true) ? exports.raw.tx.history.times(params) : exports.raw.tx.history.timesWithCache(params)) + .then(res => { + res.history = res.history ||Â {}; + // Clean sending and pendings, because already returned by tx/history/:pubkey/pending + res.history.sending = []; + res.history.pendings = []; + return res; + }); + }, blocks: get('/tx/history/:pubkey/blocks/:from/:to', csHttp.cache.LONG), pending: get('/tx/history/:pubkey/pending') } @@ -462,11 +480,19 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. uri: {}, version: {}, raw: { - requirementsWithCache: get('/wot/requirements/:pubkey', csHttp.cache.LONG), - requirementsNoCache: get('/wot/requirements/:pubkey') + wot: { + requirementsWithCache: get('/wot/requirements/:pubkey', csHttp.cache.LONG), + requirements: get('/wot/requirements/:pubkey') + }, + tx: { + history: { + timesWithCache: get('/tx/history/:pubkey/times/:from/:to', csHttp.cache.LONG), + times: get('/tx/history/:pubkey/times/:from/:to'), + all: get('/tx/history/:pubkey') + } + }, } }; - exports.regex = exports.regexp; // deprecated exports.tx.parseUnlockCondition = function(unlockCondition) { @@ -917,7 +943,7 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. csHttp.getWithCache(duniterLatestReleaseUrl.host, duniterLatestReleaseUrl.port, "/" + duniterLatestReleaseUrl.pathname, - /*useSsl*/ (duniterLatestReleaseUrl.port == 443 || duniterLatestReleaseUrl.protocol == 'https:' || that.forceUseSsl), + /*useSsl*/ (+(duniterLatestReleaseUrl.port) === 443 || duniterLatestReleaseUrl.protocol === 'https:' || that.forceUseSsl), csHttp.cache.LONG ) : // No URL define: use a fake function diff --git a/www/js/services/cache-services.js b/www/js/services/cache-services.js index 08921d8bde5ee4a73c84d8de86867979821bb5cd..a1e4f8aaa0010de22a40acdaccdf5ae9b2aa3ecc 100644 --- a/www/js/services/cache-services.js +++ b/www/js/services/cache-services.js @@ -16,9 +16,9 @@ angular.module('cesium.cache.services', ['angular-cache']) function getOrCreateCache(prefix, maxAge, onExpire){ prefix = prefix || 'csCache-'; maxAge = maxAge || constants.SHORT; - var cacheName = prefix + maxAge; + var cacheName = prefix + (maxAge / 1000); - // FIXME : enable this when cache is cleaning on rollback + // FIXME: enable this when cache is cleaning on rollback var storageMode = csSettings.data.useLocalStorage && $window.localStorage ? 'localStorage' : 'memory'; if (!onExpire) { diff --git a/www/js/services/currency-services.js b/www/js/services/currency-services.js index 1b3888305fd6b32a1b1736953a21d25ecefb5acc..4caaacf82eec57b669d880592974bdd9f941c5d3 100644 --- a/www/js/services/currency-services.js +++ b/www/js/services/currency-services.js @@ -268,7 +268,7 @@ angular.module('cesium.currency.services', ['ngApi', 'cesium.bma.services']) var now = moment().utc().unix(); if (cache) { - if (currentBlock && (now - currentBlock.receivedAt) < 60/*1min*/) { + if (currentBlock && currentBlock.receivedAt && (now - currentBlock.receivedAt) < 60/*1min*/) { //console.debug('[currency] Use current block #'+ currentBlock.number +' from cache (age='+ (now - currentBlock.receivedAt) + 's)'); return currentBlock; } @@ -283,7 +283,7 @@ angular.module('cesium.currency.services', ['ngApi', 'cesium.bma.services']) .catch(function(err){ // Special case for currency init (root block not exists): use fixed values if (err && err.ucode == BMA.errorCodes.NO_CURRENT_BLOCK) { - return {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH, medianTime: moment().utc().unix()}; + return {number: 0, hash: BMA.constants.ROOT_BLOCK_HASH, medianTime: now}; } throw err; }) diff --git a/www/js/services/settings-services.js b/www/js/services/settings-services.js index 6ac96e2e07b87f77af1f20544f489b389d96de89..c4d03f90960e3ab27161b5c89b2976acfd35122c 100644 --- a/www/js/services/settings-services.js +++ b/www/js/services/settings-services.js @@ -1,7 +1,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) -.factory('csSettings', function($rootScope, $q, Api, localStorage, $translate, csConfig) { +.factory('csSettings', function($rootScope, $q, $window, Api, localStorage, $translate, csConfig) { 'ngInject'; // Define app locales @@ -41,7 +41,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) // Convert browser locale to app locale (fix #140) function fixLocaleWithLog (locale) { var fixedLocale = fixLocale(locale); - if (locale != fixedLocale) { + if (locale !== fixedLocale) { console.debug('[settings] Fix locale [{0}] -> [{1}]'.format(locale, fixedLocale)); } return fixedLocale; @@ -67,7 +67,7 @@ angular.module('cesium.settings.services', ['ngApi', 'cesium.config']) }, defaultSettings = angular.merge({ useRelative: false, - useLocalStorage: true, // override to false if no device + useLocalStorage: !!$window.localStorage, // override to false if no device useLocalStorageEncryption: false, walletHistoryTimeSecond: 30 * 24 * 60 * 60 /*30 days*/, walletHistorySliceSecond: 5 * 24 * 60 * 60 /*download using 5 days slice*/, diff --git a/www/js/services/tx-services.js b/www/js/services/tx-services.js index 2572c44b2df78496f7acd51089fa345f278596ee..ff37081adef1ab624cca5182b06d55fda1ce2878 100644 --- a/www/js/services/tx-services.js +++ b/www/js/services/tx-services.js @@ -18,7 +18,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', if (!txArray || !txArray.length) return; // Skip if empty _.forEach(txArray, function(tx) { - if (tx.block_number || allowPendings) { + if (tx.block_number !== null || allowPendings) { var walletIsIssuer = false; var otherIssuer = tx.issuers.reduce(function(issuer, res) { walletIsIssuer = walletIsIssuer || (res === pubkey); @@ -30,7 +30,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', var otherReceiver; var outputBase; var sources = []; - var lockedOutputs; + let lockedOutputs; var amount = tx.outputs.reduce(function(sum, output, noffset) { // FIXME duniter v1.4.13 var outputArray = (typeof output == 'string') ? output.split(':',3) : [output.amount,output.base,output.conditions]; @@ -42,7 +42,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', // Simple unlock condition if (sigMatches) { var outputPubkey = sigMatches[1]; - if (outputPubkey == pubkey) { // output is for the wallet + if (outputPubkey === pubkey) { // output is for the wallet if (!walletIsIssuer) { return sum + outputAmount; } @@ -54,7 +54,8 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', type: 'T', identifier: tx.hash, noffset: noffset, - consumed: false + consumed: false, + conditions: outputCondition }); } } @@ -69,20 +70,19 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', } // Complex unlock condition, on the issuer pubkey - else if (outputCondition.indexOf('SIG('+pubkey+')') != -1) { + else if (outputCondition.indexOf('SIG('+pubkey+')') !== -1) { var lockedOutput = BMA.tx.parseUnlockCondition(outputCondition); if (lockedOutput) { // Add a source - // FIXME: should be uncomment when filtering source on transfer() - /*sources.push(angular.merge({ + sources.push(angular.merge({ amount: parseInt(outputArray[0]), base: outputBase, type: 'T', identifier: tx.hash, noffset: noffset, + conditions: outputCondition, consumed: false }, lockedOutput)); - */ lockedOutput.amount = outputAmount; lockedOutputs = lockedOutputs || []; lockedOutputs.push(lockedOutput); @@ -99,8 +99,8 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', // Avoid duplicated tx, or tx to him self var txKey = amount + ':' + tx.hash + ':' + time; - if (!processedTxMap[txKey] && amount !== 0) { - processedTxMap[txKey] = true; + if (!processedTxMap[txKey]) { + processedTxMap[txKey] = true; // Mark as processed var newTx = { time: time, amount: amount, @@ -137,10 +137,8 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', errors: [] }; - var processedTxMap = {}; - var _reduceTx = function (res) { - _reduceTxAndPush(pubkey, res.history.sent, tx.history, processedTxMap); - _reduceTxAndPush(pubkey, res.history.received, tx.history, processedTxMap); + const processedTxMap = {}; + const _reducePendingTx = function (res) { _reduceTxAndPush(pubkey, res.history.sending, tx.pendings, processedTxMap, true /*allow pendings*/); _reduceTxAndPush(pubkey, res.history.pending, tx.pendings, processedTxMap, true /*allow pendings*/); }; @@ -151,24 +149,29 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', // get pending tx BMA.tx.history.pending({pubkey: pubkey}) - .then(_reduceTx) + .then(_reducePendingTx) ]; // get TX history since if (fromTime !== 'pending') { + const _reduceTx = function (res) { + _reduceTxAndPush(pubkey, res.history.sent, tx.history, processedTxMap, false); + _reduceTxAndPush(pubkey, res.history.received, tx.history, processedTxMap, false); + }; // get TX from a given time if (fromTime > 0) { // Use slice, to be able to cache requests result - var sliceTime = csSettings.data.walletHistorySliceSecond; + const sliceTime = csSettings.data.walletHistorySliceSecond; fromTime = fromTime - (fromTime % sliceTime); for(var i = fromTime; i - sliceTime < nowInSec; i += sliceTime) { - jobs.push(BMA.tx.history.times({pubkey: pubkey, from: i, to: i+sliceTime-1}) + jobs.push(BMA.tx.history.times({pubkey: pubkey, from: i, to: i+sliceTime-1}, true /*with cache*/) .then(_reduceTx) ); } - jobs.push(BMA.tx.history.timesNoCache({pubkey: pubkey, from: nowInSec - (nowInSec % sliceTime), to: nowInSec+999999999}) + // Last slide: no cache + jobs.push(BMA.tx.history.times({pubkey: pubkey, from: nowInSec - (nowInSec % sliceTime), to: nowInSec+999999999}, false/*no cache*/) .then(_reduceTx)); } @@ -226,13 +229,11 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', tx.history.sort(function(tx1, tx2) { return (tx2.time - tx1.time); }); - tx.validating = tx.history.filter(function(tx) { - return (tx.block_number > current.number - csSettings.data.blockValidityWindow); + const firstValidatedTxIndex = tx.history.findIndex((tx) => { + return (tx.block_number <= current.number - csSettings.data.blockValidityWindow); }); // remove validating from history - if (tx.validating.length) { - tx.history.splice(0, tx.validating.length); - } + tx.validating = firstValidatedTxIndex > 0 ? tx.history.splice(0, firstValidatedTxIndex) : []; tx.fromTime = fromTime !== 'pending' && fromTime || undefined; tx.toTime = tx.history.length ? tx.history[0].time /*=max(tx.time)*/: tx.fromTime; @@ -314,7 +315,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', // TODO get sources from the issuer ? } else { - _.forEach(tx.inputs, function(input) { + _.find(tx.inputs, function(input) { var inputKey = input.split(':').slice(2).join(':'); var srcIndex = data.sourcesIndexByKey[inputKey]; if (angular.isDefined(srcIndex)) { @@ -322,7 +323,7 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', } else { valid = false; - return false; // break + return true; // break } }); if (tx.sources) { // add source output @@ -377,6 +378,10 @@ angular.module('cesium.tx.services', ['ngApi', 'cesium.bma.services', console.debug('[tx] TX and sources loaded in '+ (Date.now()-now) +'ms'); return data; }); + }) + .catch(function(err) { + console.warn("[tx] Error while getting sources and tx...", err); + throw err; }); }, diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index 5477306815f9bc1dd31b1aff27b77ac9c353b528..174ec9f68590fbae1d5953464f7a98e7b2694afa 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -120,6 +120,9 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se addSource = function(src, sources, sourcesIndexByKey) { var srcKey = src.type+':'+src.identifier+':'+src.noffset; if (angular.isUndefined(sourcesIndexByKey[srcKey])) { + if (!src.conditions) { + console.warn("Trying to add a source without output condition !", src); + } sources.push(src); sourcesIndexByKey[srcKey] = sources.length - 1; } @@ -341,7 +344,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se if (options) { if (options.minData && !options.sources) return data.loaded && true; if (options.requirements && !data.requirements.loaded) return false; - if (options.tx && options.tx.enable && (!data.tx.fromTime || data.tx.fromTime == 'pending')) return false; + if (options.tx && options.tx.enable && (!data.tx.fromTime || data.tx.fromTime === 'pending')) return false; if (options.sigStock && !data.sigStock) return false; } return data.loaded && data.sources && true; @@ -357,14 +360,18 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se !data.requirements.needSelf || data.requirements.wasMember || + // Check sources + (data.sources && data.sources.length > 0) || + // Check TX history - data.tx.history.length || - data.tx.pendings.length || + data.tx.history.length > 0 || + data.tx.validating.length > 0 || + data.tx.pendings.length > 0 || // Check extended data (name+avatar) - data.localName || - data.name || - data.avatar + !!data.localName || + !!data.name || + !!data.avatar ); }, @@ -851,7 +858,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se // Warn if wallet has been never used - see #167 .then(function() { var unused = isNeverUsed(); - var showAlert = alertIfUnusedWallet && !isNew() && angular.isDefined(unused) && unused; + var showAlert = alertIfUnusedWallet && !isNew() && unused === true; if (!showAlert) return true; return UIUtils.loading.hide() .then(function() { @@ -890,7 +897,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se }); }, - loadFullData = function() { + loadFullData = function(fromTime) { data.loaded = false; return $q.all([ @@ -907,8 +914,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se } }), - // Get TX and sources - loadTxAndSources() + // Get TX and sources (only pending by default) + loadTxAndSources(fromTime || 'pending') ]) .then(function() { @@ -951,7 +958,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se sources: true, tx: { enable: true, - fromTime: data.tx ? data.tx.fromTime : undefined // keep previous time + fromTime: data.tx && data.tx.fromTime !== 'pending' ? data.tx.fromTime : undefined // keep previous time }, sigStock: true, api: true @@ -986,8 +993,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se } else if (options.sources && (options.tx && !options.tx.enable)) { - // Get sources (no TX) - jobs.push(loadSources()); + // Get sources and only pending TX (and NOT the TX history) + jobs.push(loadTxAndSources('pending')); } // Load sigStock @@ -1425,7 +1432,9 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se type: 'T', noffset: outputOffset, amount: outputAmount, - base: outputBase + base: outputBase, + conditions: 'SIG('+restPub+')', + consumed: false }); } outputOffset++;