diff --git a/app/config.json b/app/config.json index ce4a64bc5b7462d8e52c79dcdf4f5d40ce839901..e1da45a7c006ad45ce9e53132f3d2abddd17b011 100644 --- a/app/config.json +++ b/app/config.json @@ -35,6 +35,9 @@ "port": "443" } ], + "developers": [ + {"name": "Benoit Lavenier", "pubkey": "38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE"} + ], "plugins":{ "es": { "enable": true, diff --git a/www/i18n/locale-en-GB.json b/www/i18n/locale-en-GB.json index c79263a8df87e024190c1f5da6e2b15c120a570c..4dd8db337f7d8f38e23b0c5d997b371647c6e581 100644 --- a/www/i18n/locale-en-GB.json +++ b/www/i18n/locale-en-GB.json @@ -86,9 +86,7 @@ "MENU": { "HOME": "Home", "WOT": "Registry", - "MARKET": "Market place", "CURRENCY": "Currency", - "CURRENCIES": "Currencies", "ACCOUNT": "My Account", "TRANSFER": "Transfer", "SCAN": "Scan", @@ -402,7 +400,7 @@ "USER": "Personal value", "N": "N (Loop):", "r": "r (RAM):", - "p": "p (CPU):", + "p": "p (CPU):" }, "FILE": { "DATE" : "Date:", @@ -649,7 +647,8 @@ "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:", "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account.", "GET_LICENSE_FILE_FAILED": "Unable to get license file", - "CHECK_NETWORK_CONNECTION": "No peer appears to be accessible.<br/><br/>Please <b>check your Internet connection</b>." + "CHECK_NETWORK_CONNECTION": "No peer appears to be accessible.<br/><br/>Please <b>check your Internet connection</b>.", + "ISSUE_524_TX_FAILED": "Failed to transfer.<br/><br/>A message has been sent to developers to help solve the problem.<b>Thank you for your help</b>." }, "INFO": { "POPUP_TITLE": "Information", @@ -685,7 +684,8 @@ "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?", "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved", "LOGOUT": "Are you sure you want to logout?", - "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?" + "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?", + "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>" }, "DOWNLOAD": { "POPUP_TITLE": "<b>Revocation file</b>", diff --git a/www/i18n/locale-en.json b/www/i18n/locale-en.json index 17dcd1510fd4a289133e354c18a8e2a1cf4becb3..6e4347d65240e0dc8f17727fdf318eb595ef41ea 100644 --- a/www/i18n/locale-en.json +++ b/www/i18n/locale-en.json @@ -86,9 +86,7 @@ "MENU": { "HOME": "Home", "WOT": "Registry", - "MARKET": "Market place", "CURRENCY": "Currency", - "CURRENCIES": "Currencies", "ACCOUNT": "My Account", "TRANSFER": "Transfer", "SCAN": "Scan", @@ -402,7 +400,7 @@ "USER": "Personal value", "N": "N (Loop):", "r": "r (RAM):", - "p": "p (CPU):", + "p": "p (CPU):" }, "FILE": { "DATE" : "Date:", @@ -649,7 +647,8 @@ "EXISTING_ACCOUNT": "Your identifiers correspond to an already existing account, whose <a ng-click=\"showHelpModal('pubkey')\">public key</a> is:", "EXISTING_ACCOUNT_REQUEST": "Please modify your credentials so that they correspond to an unused account.", "GET_LICENSE_FILE_FAILED": "Unable to get license file", - "CHECK_NETWORK_CONNECTION": "No peer appears to be accessible.<br/><br/>Please <b>check your Internet connection</b>." + "CHECK_NETWORK_CONNECTION": "No peer appears to be accessible.<br/><br/>Please <b>check your Internet connection</b>.", + "ISSUE_524_TX_FAILED": "Failed to transfer.<br/><br/>A message has been sent to developers to help solve the problem.<b>Thank you for your help</b>." }, "INFO": { "POPUP_TITLE": "Information", @@ -685,7 +684,8 @@ "SAVE_BEFORE_LEAVE": "Do you want to <b>save your changes</b> before leaving the page?", "SAVE_BEFORE_LEAVE_TITLE": "Changes not saved", "LOGOUT": "Are you sure you want to logout?", - "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?" + "USE_FALLBACK_NODE": "Peer <b>{{old}}</b> unreachable or invalid address.<br/><br/>Do you want to temporarily use the <b>{{new}}</b> node?", + "ISSUE_524_SEND_LOG": "The transaction was rejected because of a known problem (issue #524) but not reproduced.<br/><br/>To help developers correct this error, do you accept <b>the transmission of your logs</b> per message?<br/><small>(No confidential data is sent)</small>" }, "DOWNLOAD": { "POPUP_TITLE": "<b>Revocation file</b>", diff --git a/www/i18n/locale-fr-FR.json b/www/i18n/locale-fr-FR.json index 5c92c4295f2b1c0276d7dfc45815bbcca5aef600..41a2581102333f769de6b18d4db69589a2ef6060 100644 --- a/www/i18n/locale-fr-FR.json +++ b/www/i18n/locale-fr-FR.json @@ -400,7 +400,7 @@ "USER": "Sallage personnalisé", "N": "N (Loop):", "r": "r (RAM):", - "p": "p (CPU):", + "p": "p (CPU):" }, "FILE": { "DATE" : "Date :", @@ -647,7 +647,8 @@ "EXISTING_ACCOUNT": "Vos identifiants correspondent à un compte déjà existant, dont la <a ng-click=\"showHelpModal('pubkey')\">clef publique</a> est :", "EXISTING_ACCOUNT_REQUEST": "Veuillez modifier vos identifiants afin qu'ils correspondent à un compte non utilisé.", "GET_LICENSE_FILE_FAILED": "Récupérer du fichier de licence impossible", - "CHECK_NETWORK_CONNECTION": "Aucun nœud ne semble accessible.<br/><br/>Veuillez <b>vérifier votre connection Internet</b>." + "CHECK_NETWORK_CONNECTION": "Aucun nœud ne semble accessible.<br/><br/>Veuillez <b>vérifier votre connection Internet</b>.", + "ISSUE_524_TX_FAILED": "Echec du virement.<br/><br/>Un message a été envoyé aux développeurs pour faciliter la résolution du problème. <b>Merci de votre aide</b>." }, "INFO": { "POPUP_TITLE": "Information", @@ -683,7 +684,8 @@ "SAVE_BEFORE_LEAVE": "Voulez-vous <b>sauvegarder vos modifications</b> avant de quitter la page ?", "SAVE_BEFORE_LEAVE_TITLE": "Modifications non enregistrées", "LOGOUT": "Etes-vous de vouloir vous déconnecter ?", - "USE_FALLBACK_NODE": "Nœud <b>{{old}}</b> injoignable ou adresse invalide.<br/><br/>Voulez-vous temporairement utiliser le nœud <b>{{new}}</b> ?" + "USE_FALLBACK_NODE": "Nœud <b>{{old}}</b> injoignable ou adresse invalide.<br/><br/>Voulez-vous temporairement utiliser le nœud <b>{{new}}</b> ?", + "ISSUE_524_SEND_LOG": "La transaction a été rejettée, à cause d'une anomalie connue (ticket #524) mais <b>non reproduite</b>.<br/><br/>Pour nous aider les développeurs à corriger cette erreur, <b>acceptez-vous la transmission de vos logs</b> par message ?<br/><small>(Aucune donnée confidentielle n'est envoyée)</small>." }, "DOWNLOAD": { "POPUP_TITLE": "<b>Fichier de révocation</b>", diff --git a/www/js/config.js b/www/js/config.js index 920f22d51589916b60ead090af586647dae3dee3..219300f97e6cc1e65d83e233e04b68b4f3d7457b 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -44,6 +44,12 @@ angular.module("cesium.config", []) "port": "443" } ], + "developers": [ + { + "name": "Benoit Lavenier", + "pubkey": "38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE" + } + ], "plugins": { "es": { "enable": true, @@ -60,7 +66,7 @@ angular.module("cesium.config", []) } }, "version": "0.15.5", - "build": "2017-08-08T15:24:29.307Z", + "build": "2017-08-09T10:46:18.654Z", "newIssueUrl": "https://github.com/duniter/cesium/issues/new?labels=bug" }) diff --git a/www/js/services/bma-services.js b/www/js/services/bma-services.js index 3b7a2f701e4996f139825e723a31e014f9bcad48..fb722339d2a3ba271626931c92639859b54a30b8 100644 --- a/www/js/services/bma-services.js +++ b/www/js/services/bma-services.js @@ -43,6 +43,8 @@ angular.module('cesium.bma.services', ['ngApi', 'cesium.http.services', 'cesium. MEMBERSHIP_ALREADY_SEND: 2007, NO_CURRENT_BLOCK: 2010, BLOCK_NOT_FOUND: 2011, + TX_INPUTS_OUTPUTS_NOT_EQUAL: 2024, + TX_OUTPUT_SUM_NOT_EQUALS_PREV_DELTAS: 2025, TX_ALREADY_PROCESSED: 2030 }, constants = { diff --git a/www/js/services/utils-services.js b/www/js/services/utils-services.js index 8fa58bbb9303f3b845f1b1c0be0ad41bf0187cef..f99cba37f2ae0369ca27a21aec1f8efe6d9f6c09 100644 --- a/www/js/services/utils-services.js +++ b/www/js/services/utils-services.js @@ -108,7 +108,7 @@ angular.module('cesium.utils.services', []) cancelText: translations[options.cancelText], cancelType: options.cancelType, okText: translations[options.okText], - okType: options.okType, + okType: options.okType }); }); } diff --git a/www/js/services/wallet-services.js b/www/js/services/wallet-services.js index da58ba35d5b7f162e939acc8598066619ad89464..aefe3318c00b700f30a3ed065d6816d42a3a88dc 100644 --- a/www/js/services/wallet-services.js +++ b/www/js/services/wallet-services.js @@ -841,6 +841,9 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se sources : [] }; + var logs = []; + logs.push("[wallet] amount=" + amount); + // Get inputs, starting to use current base sources var amountBase = 0; while (inputs.amount < amount && amountBase <= block.unitbase) { @@ -851,6 +854,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se amountBase++; if (amountBase <= block.unitbase) { amount = truncBase(amount, amountBase); + logs.push("[wallet] inputs not found. Retrying with amount =" + amount + " be compatible with amountBase=" + amountBase); } } } @@ -891,13 +895,15 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se if (amountBase < inputs.minBase && !isBase(amount, inputs.minBase)) { amount = truncBaseOrMinBase(amount, inputs.minBase); console.debug("[wallet] Amount has been truncate to " + amount); + logs.push("[wallet] Amount has been truncate to " + amount); } else if (amountBase > 0) { console.debug("[wallet] Amount has been truncate to " + amount); + logs.push("[wallet] Will use amount truncated to " + amount + " (amountBase="+amountBase+")"); } // Send tx - return createAndSendTx(currency, block, keypair, destPub, amount, inputs, comments) + return createAndSendTx(currency, block, keypair, destPub, amount, inputs, comments, logs) .then(function(res) { data.balance -= amount; _.forEach(inputs.sources, function(source) { @@ -928,6 +934,35 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se api.data.raise.balanceChanged(data); api.data.raise.newTx(data); }); + }) + .catch(function(err) { + if (err && err.ucode === BMA.errorCodes.TX_INPUTS_OUTPUTS_NOT_EQUAL) { + // Send log message for debugging - issue #524 - https://github.com/duniter/cesium/issues/524 + var esEnable = csSettings.data.plugins && csSettings.data.plugins.es && csSettings.data.plugins.es.enable; + if (esEnable) { + UIUtils.loading.hide(); + return UIUtils.alert.confirm('CONFIRM.ISSUE_524_SEND_LOG', 'ERROR.POPUP_TITLE', { + cssClass: 'warning', + okText: 'COMMON.BTN_OK', + cancelText: 'COMMON.BTN_NO' + }) + .then(function(confirm) { + if (confirm) { + api.error.raise.send({ + title: 'Issue #524 logs', + content: 'App version: ' +csConfig.version+'\n'+ + 'App build: ' +csConfig.build+'\n'+ + 'Logs:\n\n' + logs.join('\n') + }); + return $timeout(function() { + throw {message: 'ERROR.ISSUE_524_TX_FAILED'}; + }, 1500); + } + throw {message: 'ERROR.SEND_TX_FAILED'}; + }); + } + } + throw err; }); }); }, @@ -941,7 +976,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se * @param comments * @return the hash of the sent TX */ - createAndSendTx = function(currency, block, keypair, destPub, amount, inputs, comments) { + createAndSendTx = function(currency, block, keypair, destPub, amount, inputs, comments, logs) { // Make sure a TX in compact mode has no more than 100 lines (fix #118) // (If more than 100 lines, send to TX to himself first, then its result as sources for the final TX) @@ -962,7 +997,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se }); // Send inputs first slice - return createAndSendTx(currency, block, keypair, data.pubkey/*to himself*/, firstSlice.amount, firstSlice) // comment not need + return createAndSendTx(currency, block, keypair, data.pubkey/*to himself*/, firstSlice.amount, firstSlice, undefined/*comment not need*/, logs) .then(function(res) { _.forEach(firstSlice.sources, function(source) { source.consumed=true; @@ -982,7 +1017,7 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se }); // Send inputs second slice (recursive call) - return createAndSendTx(currency, block, keypair, destPub, amount, secondSlice, comments); + return createAndSendTx(currency, block, keypair, destPub, amount, secondSlice, comments, logs); }); } @@ -1049,6 +1084,20 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se tx += "Comment: "+ (comments||"") + "\n"; + // Append to logs (need to resolve issue #524) + if (logs) { + if (destPub == data.pubkey) { + logs.push('[wallet] Creating new TX, using inputs:\n - minBase: '+inputs.minBase+'\n - maxBase: '+inputs.maxBase); + } + else { + logs.push('[wallet] Creating new TX, using inputs:\n - minBase: '+inputs.minBase+'\n - maxBase: '+inputs.maxBase + '\n - sources (=TX inputs):'); + } + _.forEach(inputs.sources, function(source) { + logs.push([source.amount, source.base, source.type, source.identifier,source.noffset].join(':')); + }); + logs.push("\n[wallet] generated TX document (without signature) :\n------ START ------\n" + tx + "------ END ------\n"); + } + return CryptoUtils.sign(tx, keypair) .then(function(signature) { var signedTx = tx + signature + "\n"; @@ -1632,6 +1681,8 @@ angular.module('cesium.wallet.services', ['ngApi', 'ngFileSaver', 'cesium.bma.se api.registerEvent('data', 'logout'); api.registerEvent('data', 'reset'); + api.registerEvent('error', 'send'); + // Data changed : balance changed, new TX api.registerEvent('data', 'balanceChanged'); api.registerEvent('data', 'newTx'); diff --git a/www/plugins/es/js/services/message-services.js b/www/plugins/es/js/services/message-services.js index 6f3580469839a99d29931ed8f44bf364f5344e64..668fadd969218a2ee57b61b040ea032dbe0986dc 100644 --- a/www/plugins/es/js/services/message-services.js +++ b/www/plugins/es/js/services/message-services.js @@ -11,7 +11,8 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.platform', }) -.factory('esMessage', function($q, $rootScope, Api, CryptoUtils, csPlatform, csSettings, esHttp, csWallet, esWallet, csWot, esNotification) { +.factory('esMessage', function($q, $rootScope, $timeout, UIUtils, Api, CryptoUtils, + csPlatform, csConfig, csSettings, esHttp, csWallet, esWallet, csWot, esNotification) { 'ngInject'; var @@ -444,6 +445,28 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.platform', }); } + // Send message to developers - need for issue #524 + function onSendError(message) { + var developers = csConfig.developers || [{pubkey: '38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE'/*kimamila*/}]; + if(!message || !message.content || !developers || !developers.length) return; + + console.info("[ES] [message] Sending logs to developers..."); + message.issuer = csWallet.data.pubkey; + message.title = message.title || 'Sending log'; + message.time = esHttp.date.now(); + + csWallet.getKeypair() + .then(function(keypair) { + return $q.all(developers.reduce(function(res, developer){ + return !developer.pubkey ? res : + res.concat(sendMessage(angular.merge({recipient: developer.pubkey}, message), keypair)); + }, [])); + }) + .then(function(res) { + console.info("[ES] [message] Logs sent to {0} developers".format(res.length)); + }); + } + function removeListeners() { _.forEach(listeners, function(remove){ remove(); @@ -457,7 +480,9 @@ angular.module('cesium.es.message.services', ['ngResource', 'cesium.platform', csWallet.api.data.on.login($rootScope, onWalletLogin, this), csWallet.api.data.on.init($rootScope, onWalletInit, this), csWallet.api.data.on.reset($rootScope, onWalletReset, this), - esNotification.api.event.on.newMessage($rootScope, onNewMessageEvent, this) + esNotification.api.event.on.newMessage($rootScope, onNewMessageEvent, this), + // for issue #524 + csWallet.api.error.on.send($rootScope, onSendError, this) ]; }