|
|
@ -6,8 +6,12 @@ const ObservableStore = require('obs-store') |
|
|
|
const ethUtil = require('ethereumjs-util') |
|
|
|
const ethUtil = require('ethereumjs-util') |
|
|
|
const TxProviderUtil = require('../lib/tx-utils') |
|
|
|
const TxProviderUtil = require('../lib/tx-utils') |
|
|
|
const createId = require('../lib/random-id') |
|
|
|
const createId = require('../lib/random-id') |
|
|
|
|
|
|
|
const denodeify = require('denodeify') |
|
|
|
|
|
|
|
|
|
|
|
module.exports = class TransactionManager extends EventEmitter { |
|
|
|
const RETRY_LIMIT = 200 |
|
|
|
|
|
|
|
const RESUBMIT_INTERVAL = 10000 // Ten seconds
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = class TransactionController extends EventEmitter { |
|
|
|
constructor (opts) { |
|
|
|
constructor (opts) { |
|
|
|
super() |
|
|
|
super() |
|
|
|
this.store = new ObservableStore(extend({ |
|
|
|
this.store = new ObservableStore(extend({ |
|
|
@ -30,6 +34,8 @@ module.exports = class TransactionManager extends EventEmitter { |
|
|
|
this.store.subscribe(() => this._updateMemstore()) |
|
|
|
this.store.subscribe(() => this._updateMemstore()) |
|
|
|
this.networkStore.subscribe(() => this._updateMemstore()) |
|
|
|
this.networkStore.subscribe(() => this._updateMemstore()) |
|
|
|
this.preferencesStore.subscribe(() => this._updateMemstore()) |
|
|
|
this.preferencesStore.subscribe(() => this._updateMemstore()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.continuallyResubmitPendingTxs() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
getState () { |
|
|
|
getState () { |
|
|
@ -229,7 +235,11 @@ module.exports = class TransactionManager extends EventEmitter { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
publishTransaction (txId, rawTx, cb) { |
|
|
|
publishTransaction (txId, rawTx, cb = warn) { |
|
|
|
|
|
|
|
const txMeta = this.getTx(txId) |
|
|
|
|
|
|
|
txMeta.rawTx = rawTx |
|
|
|
|
|
|
|
this.updateTx(txMeta) |
|
|
|
|
|
|
|
|
|
|
|
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { |
|
|
|
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => { |
|
|
|
if (err) return cb(err) |
|
|
|
if (err) return cb(err) |
|
|
|
this.setTxHash(txId, txHash) |
|
|
|
this.setTxHash(txId, txHash) |
|
|
@ -352,7 +362,7 @@ module.exports = class TransactionManager extends EventEmitter { |
|
|
|
message: 'There was a problem loading this transaction.', |
|
|
|
message: 'There was a problem loading this transaction.', |
|
|
|
} |
|
|
|
} |
|
|
|
this.updateTx(txMeta) |
|
|
|
this.updateTx(txMeta) |
|
|
|
return console.error(err) |
|
|
|
return log.error(err) |
|
|
|
} |
|
|
|
} |
|
|
|
if (txParams.blockNumber) { |
|
|
|
if (txParams.blockNumber) { |
|
|
|
this.setTxStatusConfirmed(txId) |
|
|
|
this.setTxStatusConfirmed(txId) |
|
|
@ -378,6 +388,7 @@ module.exports = class TransactionManager extends EventEmitter { |
|
|
|
this.emit(`${txMeta.id}:${status}`, txId) |
|
|
|
this.emit(`${txMeta.id}:${status}`, txId) |
|
|
|
if (status === 'submitted' || status === 'rejected') { |
|
|
|
if (status === 'submitted' || status === 'rejected') { |
|
|
|
this.emit(`${txMeta.id}:finished`, txMeta) |
|
|
|
this.emit(`${txMeta.id}:finished`, txMeta) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
this.updateTx(txMeta) |
|
|
|
this.updateTx(txMeta) |
|
|
|
this.emit('updateBadge') |
|
|
|
this.emit('updateBadge') |
|
|
@ -397,7 +408,47 @@ module.exports = class TransactionManager extends EventEmitter { |
|
|
|
}) |
|
|
|
}) |
|
|
|
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList }) |
|
|
|
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList }) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
continuallyResubmitPendingTxs () { |
|
|
|
|
|
|
|
const pending = this.getTxsByMetaData('status', 'submitted') |
|
|
|
|
|
|
|
const resubmit = denodeify(this.resubmitTx.bind(this)) |
|
|
|
|
|
|
|
Promise.all(pending.map(txMeta => resubmit(txMeta))) |
|
|
|
|
|
|
|
.catch((reason) => { |
|
|
|
|
|
|
|
log.info('Problem resubmitting tx', reason) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.then(() => { |
|
|
|
|
|
|
|
global.setTimeout(() => { |
|
|
|
|
|
|
|
this.continuallyResubmitPendingTxs() |
|
|
|
|
|
|
|
}, RESUBMIT_INTERVAL) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resubmitTx (txMeta, cb) { |
|
|
|
|
|
|
|
// Increment a try counter.
|
|
|
|
|
|
|
|
if (!('retryCount' in txMeta)) { |
|
|
|
|
|
|
|
txMeta.retryCount = 0 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Only auto-submit already-signed txs:
|
|
|
|
|
|
|
|
if (!('rawTx' in txMeta)) { |
|
|
|
|
|
|
|
return cb() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (txMeta.retryCount > RETRY_LIMIT) { |
|
|
|
|
|
|
|
txMeta.err = { |
|
|
|
|
|
|
|
isWarning: true, |
|
|
|
|
|
|
|
message: 'Gave up submitting tx.', |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.updateTx(txMeta) |
|
|
|
|
|
|
|
return log.error(txMeta.err.message) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
txMeta.retryCount++ |
|
|
|
|
|
|
|
const rawTx = txMeta.rawTx |
|
|
|
|
|
|
|
this.txProviderUtils.publishTransaction(rawTx, cb) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const warn = () => console.warn('warn was used no cb provided') |
|
|
|
const warn = () => log.warn('warn was used no cb provided') |
|
|
|