Auto fail transactions that have been approved for over 12 hours (#5765)

* Auto fail transactions that have been approved for over 12 hours

Converts txs using a migration.

This migration uses a new helper function that generates tx-failing
migrations, and only requires a version, error message, and condition to
run on each transaction.

* Linted

* Only migrate approved txs to failed

* Cleanup

* Cleanup

* Small lint fixes
feature/default_network_editable
Dan Finlay 6 years ago committed by GitHub
parent 1988e1e96b
commit fdea642e6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      app/scripts/migrations/029.js
  2. 41
      app/scripts/migrations/fail-tx.js
  3. 1
      app/scripts/migrations/index.js
  4. 38
      test/unit/migrations/029-test.js

@ -0,0 +1,27 @@
// next version number
const version = 29
const failTxsThat = require('./fail-tx')
// time
const seconds = 1000
const minutes = 60 * seconds
const hours = 60 * minutes
const unacceptableDelay = 12 * hours
/*
normalizes txParams on unconfirmed txs
*/
module.exports = {
version,
migrate: failTxsThat(version, 'Stuck in approved state for too long.', (txMeta) => {
const isApproved = txMeta.status === 'approved'
const createdTime = txMeta.submittedTime
const now = Date.now()
return isApproved && now - createdTime > unacceptableDelay
}),
}

@ -0,0 +1,41 @@
const clone = require('clone')
module.exports = function (version, reason, condition) {
return function (originalVersionedData) {
const versionedData = clone(originalVersionedData)
versionedData.meta.version = version
try {
const state = versionedData.data
const newState = transformState(state, condition, reason)
versionedData.data = newState
} catch (err) {
console.warn(`MetaMask Migration #${version}` + err.stack)
}
return Promise.resolve(versionedData)
}
}
function transformState (state, condition, reason) {
const newState = state
const { TransactionController } = newState
if (TransactionController && TransactionController.transactions) {
const transactions = TransactionController.transactions
newState.TransactionController.transactions = transactions.map((txMeta) => {
if (!condition(txMeta)) {
return txMeta
}
txMeta.status = 'failed'
txMeta.err = {
message: reason,
note: `Tx automatically failed by migration because ${reason}`,
}
return txMeta
})
}
return newState
}

@ -39,4 +39,5 @@ module.exports = [
require('./026'),
require('./027'),
require('./028'),
require('./029'),
]

@ -0,0 +1,38 @@
const assert = require('assert')
const migration29 = require('../../../app/scripts/migrations/029')
const properTime = (new Date()).getTime()
const storage = {
'meta': {},
'data': {
'TransactionController': {
'transactions': [
{ 'status': 'approved', id: 1, submittedTime: 0 },
{ 'status': 'approved', id: 2, submittedTime: properTime },
{ 'status': 'confirmed', id: 3, submittedTime: properTime },
{ 'status': 'submitted', id: 4, submittedTime: properTime },
{ 'status': 'submitted', id: 5, submittedTime: 0 },
],
},
},
}
describe('storage is migrated successfully where transactions that are submitted have submittedTimes', () => {
it('should auto fail transactions more than 12 hours old', (done) => {
migration29.migrate(storage)
.then((migratedData) => {
const txs = migratedData.data.TransactionController.transactions
const [ txMeta1 ] = txs
assert.equal(migratedData.meta.version, 29)
assert.equal(txMeta1.status, 'failed', 'old tx is auto failed')
assert(txMeta1.err.message.includes('too long'), 'error message assigned')
txs.forEach((tx) => {
if (tx.id === 1) return
assert.notEqual(tx.status, 'failed', 'other tx is not auto failed')
})
done()
}).catch(done)
})
})
Loading…
Cancel
Save