From e2a8077745c9d9b37841383b3a2bf03b661f12b6 Mon Sep 17 00:00:00 2001 From: Chris Dukakis Date: Thu, 21 Dec 2017 13:27:42 +0200 Subject: [PATCH] Check inclusion states before promoting (#831) --- locales/en/translation.json | 2 - ui/js/ui.history.js | 107 +++++++++++++++++++++--------------- ui/js/ui.recover.js | 90 +++++++++++++++--------------- 3 files changed, 105 insertions(+), 94 deletions(-) diff --git a/locales/en/translation.json b/locales/en/translation.json index ce137d33..69785486 100644 --- a/locales/en/translation.json +++ b/locales/en/translation.json @@ -345,8 +345,6 @@ "cannot_close_whilst_recovering": "Cannot close whilst recovering", "recovery_new_seed_prompt": "Enter your new seed below. The address at key index 0 should be unused it is where you will receive your tokens into during the reveal phase.", "recovery_reattach_prompt": "Please wait for the confirmation of the proof transaction and make use of the promote/reattach button if it is pending for too long. A proof is only accepted once it's confirmed.", - "reattach_not_required": "Wait a few seconds before reattaching", - "promote_not_required": "Wait a few seconds before promoting", "recovery_proof_transaction_pending": "Proof transaction is pending", "recovery_proof_transaction_confirmed": "Proof transaction confirmed", "recovery_reveal_transaction_pending": "Reveal transaction is pending", diff --git a/ui/js/ui.history.js b/ui/js/ui.history.js index 6c11f269..c8e1dec3 100644 --- a/ui/js/ui.history.js +++ b/ui/js/ui.history.js @@ -219,6 +219,8 @@ var UI = (function(UI, $, undefined) { }); } else if (isPromote) { function _resetUI (err, success, desktopNotification) { + $('#promote-btn .progress').hide() + if (err) { $('#promote-btn').loadingError(err) } else { @@ -238,67 +240,82 @@ var UI = (function(UI, $, undefined) { } function _promote (tail, count, i, skipCheck) { - console.log(tail) - UI.isDoingPOW = true + iota.api.getLatestInclusion([tail.hash], (err, states) => { + if (err) { + _resetUI(err.message) + return + } - const spamTransfer = [{address: '9'.repeat(81), value: 0, message: '', tag: ''}] + if (states[0]) { + $('#bundle-modal').find('.btn').hide() + $('#bundle-modal').find(".persistence").html("" + UI.t("persistence") + ": " + UI.t('confirmed') + "").show() - if (!skipCheck && !isAboveMaxDepth(tail)) { - _resetUI('promote_bellow_max_depth_error') + UI.updateState(1000) - bundlesToTailsMap.delete(bundleHash) + _resetUI(null, 'promote_completed', 'transaction_promoted_successfully') + return + } - $('#reattach-btn').show() - $('#promote-btn').loadingReset('promote') - $('#promote-btn').hide() - } + const spamTransfer = [{address: '9'.repeat(81), value: 0, message: '', tag: ''}] - $('#promote-btn').loadingReset() + if (!skipCheck && !isAboveMaxDepth(tail)) { + _resetUI('promote_bellow_max_depth_error') - var $bar = $('
') + bundlesToTailsMap.delete(bundleHash) - if (i === 1) { - $('#promote-btn').append($bar) - } - $('#promote-btn .progress').show() + $('#reattach-btn').show() + $('#promote-btn').loadingReset('promote') + $('#promote-btn').hide() + return + } - $('#promote-btn').loadingUpdate(UI.t('promoting') + ' ' + i + '/' + count) + $('#promote-btn').loadingReset() - iota.api.promoteTransaction( - tail.hash, - connection.depth, - connection.minWeightMagnitude, - spamTransfer, - {interrupt: false, delay: 0}, - (err, res) => { - UI.isDoingPOW = false + var $bar = $('
') - if (err) { - if (err.message.indexOf('Inconsistent subtangle') > -1) { - _resetUI('promote_inconsistent_subtangle_error') + if (i === 1) { + $('#promote-btn').append($bar) + } + $('#promote-btn .progress').show() - bundlesToTailsMap.delete(bundleHash) + $('#promote-btn').loadingUpdate(UI.t('promoting') + ' ' + i + '/' + count) - $('#promote-btn').hide() - $('#promote-btn').loadingReset('promote') - $('#reattach-btn').show() - } else { - _resetUI(err.message) - } - } else { - if (i < count) { - setTimeout(() => _promote(tail, count, ++i, true), 1000) - return - } + UI.isDoingPOW = true + + iota.api.promoteTransaction( + tail.hash, + connection.depth, + connection.minWeightMagnitude, + spamTransfer, + {interrupt: false, delay: 0}, + (err, res) => { + UI.isDoingPOW = false - $('#promote-btn .progress').hide() + if (err) { + if (err.message.indexOf('Inconsistent subtangle') > -1) { + _resetUI('promote_inconsistent_subtangle_error') - UI.updateState(1000) + bundlesToTailsMap.delete(bundleHash) - _resetUI(null, 'promote_completed', 'transaction_promoted_successfully') + $('#promote-btn').hide() + $('#promote-btn').loadingReset('promote') + $('#reattach-btn').show() + } else { + _resetUI(err.message) + } + } else { + if (i < count) { + setTimeout(() => _promote(tail, count, ++i, true), 1000) + return + } + + UI.updateState(1000) + + _resetUI(null, 'promote_completed', 'transaction_promoted_successfully') + } } - } - ) + ) + }) } _promote(bundlesToTailsMap.get(bundleHash), 5, 1, false) } else { diff --git a/ui/js/ui.recover.js b/ui/js/ui.recover.js index d93bafc1..7424f28d 100644 --- a/ui/js/ui.recover.js +++ b/ui/js/ui.recover.js @@ -44,6 +44,8 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg var _bundlesToTailsMap = new Map() var _proofTx = null var _revealTx = null + var _proofTails = [] + var _revealTails = [] var _proofTxConfirmed = false var _revealTxConfirmed = false var _proofAddress = '' @@ -146,6 +148,7 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg recoveryNextBtn.loadingReset('recovery_next') return } + _proofTails = tails _proofTx = [txs.filter(tx => tx.lastIndex === 0).sort((a, b) => a.timestamp - b.timestamp)[0]] _step++ $('#recovery-step-1').hide() @@ -205,12 +208,13 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg $('#recovery-transaction-hash-clipboard').html(UI.formatForClipboard(tx[0].hash)) _bundlesToTailsMap.set(tx[0].bundle, tx[0]) _step++ + _proofTx = tx checkInclusionStates(tx, CONFIRMATION_CHECK_TIMEOUT, false, (err, confirmed, tails) => { if (err) { UI.formError('recover', err.message, {initial: 'recovery_next'}) return } - _proofTx = tx + _proofTails = tails if (confirmed) { _proofTxConfirmed = true UI.formSuccess('recover', 'recovery_proof_transaction_confirmed') @@ -266,12 +270,6 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg e.preventDefault() e.stopPropagation() }) - if (!_proofTx) { - UI.formError('recover', 'reattach_not_required', {initial: 'reattach'}) - reattachBtn.loadingReset('reattach') - $('.remodal-close').off('click') - return - } reattach(_proofTx[0].hash).then(res => { reattachBtn.loadingReset('reattach') UI.formSuccess('recover', 'reattach_completed', {initial: 'reattach'}) @@ -294,14 +292,8 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg e.preventDefault() e.stopPropagation() }) - if (!_proofTx) { - UI.formError('recover', 'promote_not_required', {initial: 'promote'}) - promoteBtn.loadingReset('promote') - $('.remodal-close').off('click') - return - } const tail = _bundlesToTailsMap.get(_proofTx[0].bundle) || _proofTx[0] - promote(tail, _bundlesToTailsMap, 5, 1, (err, res) => { + promote(tail, _proofTails, _bundlesToTailsMap, 5, 1, (err, res) => { if (err) { if (err.message.indexOf('Inconsistent subtangle') > -1) { UI.formError('recover', 'promote_inconsistent_subtangle_error') @@ -325,14 +317,8 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg e.preventDefault() e.stopPropagation() }) - if (!_revealTx) { - UI.formError('recover', 'promote_not_required', {initial: 'promote'}) - recoverySubmitSeedPromoteBtn.loadingReset('promote') - $('.remodal-close').off('click') - return - } const tail = _bundlesToTailsMap.get(_revealTx[0].bundle) || _revealTx[0] - promote(tail, _bundlesToTailsMap, 5, 1, (err, res) => { + promote(tail, _revealTails, _bundlesToTailsMap, 5, 1, (err, res) => { if (err) { if (err.message.indexOf('Inconsistent subtangle') > -1) { UI.formError('recover', 'promote_inconsistent_subtangle_error') @@ -357,12 +343,6 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg e.preventDefault() e.stopPropagation() }) - if (!_revealTx) { - UI.formError('recover', 'reattach_not_required', {initial: 'reattach'}) - recoverySubmitSeedReattachBtn.loadingReset('reattach') - $('.remodal-close').off('click') - return - } reattach(_revealTx[0].hash).then(res => { recoverySubmitSeedReattachBtn.loadingReset('reattach') _pauseConfCheck = false @@ -415,12 +395,13 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg $('#recovery-proof-confirmed-status').hide() $('#recovery-reveal-confirmed-status').fadeIn() $('#recovery-transaction-hash-clipboard').html(UI.formatForClipboard(txs[0].hash)) + _revealTx = txs checkInclusionStates(txs, CONFIRMATION_CHECK_TIMEOUT, false, (err, confirmed, tails) => { if (err) { UI.formError('recover', err.message, {initial: 'recovery_next'}) return } - _revealTx = txs + _revealTails = tails if (confirmed) { UI.formSuccess('recover', 'recovery_completed', {initial: 'recovery_submit_seed'}) $('.remodal-close').off('click') @@ -493,6 +474,8 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg _bundlesToTailsMap = new Map() _proofTx = null _revealTx = null + _proofTails = [] + _revealTails = [] _proofTxConfirmed = false _revealTxConfirmed = false _proofAddress = '' @@ -590,27 +573,40 @@ WHGl/N/YlZ/p38kb7ZXtuRca7VUPxRzqv3FrUBg ) } - function promote (tail, bundlesToTailsMap, count, i, cb) { - iota.api.promoteTransaction( - tail.hash, - connection.depth, - connection.minWeightMagnitude, - [{ address: '9'.repeat(81), value: 0, message: '', tag: '' }], - { interrupt: false, delay: 0 }, - (err, res) => { - if (err) { - if (err.message.indexOf('Inconsistent subtangle') > -1) { - bundlesToTailsMap.delete(tail.bundle) + function promote (tail, tails, bundlesToTailsMap, count, i, cb) { + if (!tails || !tails.length) { + tails = [tail] + } + iota.api.getLatestInclusion(tails.map(tx => tx.hash), (err, states) => { + if (err) { + return cb(err) + } + + if (states.some(state => state)) { + return cb(null, true) + } + + iota.api.promoteTransaction( + tail.hash, + connection.depth, + connection.minWeightMagnitude, + [{ address: '9'.repeat(81), value: 0, message: '', tag: '' }], + { interrupt: false, delay: 0 }, + (err, res) => { + if (err) { + if (err.message.indexOf('Inconsistent subtangle') > -1) { + bundlesToTailsMap.delete(tail.bundle) + } + return cb(err) + } + if (i < count) { + setTimeout(() => promote(tail, tails, bundlesToTailsMap, count, ++i, cb), 1000) + } else { + cb(null, res) } - return cb(err) - } - if (i < count) { - setTimeout(() => promote(tail, bundlesToTailsMap, count, ++i, cb)) - } else { - cb(null, res) } - } - ) + ) + }) } function generateProofBundle (address, pepperAndProof, tag) {