meta - transactions - code clean up and jsDoc

feature/default_network_editable
frankiebee 7 years ago
parent 3aaa28531e
commit 88f4212363
  1. 150
      app/scripts/controllers/transactions/index.js
  2. 4
      test/unit/tx-controller-test.js

@ -8,22 +8,37 @@ const TxGasUtil = require('./tx-gas-utils')
const PendingTransactionTracker = require('./pending-tx-tracker') const PendingTransactionTracker = require('./pending-tx-tracker')
const NonceTracker = require('./nonce-tracker') const NonceTracker = require('./nonce-tracker')
const txUtils = require('./lib/util') const txUtils = require('./lib/util')
/*
module.exports = TransactionController
/**
Transaction Controller is an aggregate of sub-controllers and trackers Transaction Controller is an aggregate of sub-controllers and trackers
composing them in a way to be exposed to the metamask controller composing them in a way to be exposed to the metamask controller
- txStateManager <br>- txStateManager
responsible for the state of a transaction and responsible for the state of a transaction and
storing the transaction storing the transaction
- pendingTxTracker <br>- pendingTxTracker
watching blocks for transactions to be include watching blocks for transactions to be include
and emitting confirmed events and emitting confirmed events
- txGasUtil <br>- txGasUtil
gas calculations and safety buffering gas calculations and safety buffering
- nonceTracker <br>- nonceTracker
calculating nonces calculating nonces
@param {object} opts -
- initState, initial transaction list default is an empty array<br>
- networkStore, an observable store for network number<br>
- blockTracker,<br>
- provider,<br>
- signTransaction, function the signs an ethereumjs-tx<br>
- getGasPrice, optional gas price calculator<br>
- txHistoryLimit, number *optional* for limiting how many transactions are in state <br>
- preferencesStore,
@class
*/ */
module.exports = class TransactionController extends EventEmitter { class TransactionController extends EventEmitter {
constructor (opts) { constructor (opts) {
super() super()
this.networkStore = opts.networkStore || new ObservableStore({}) this.networkStore = opts.networkStore || new ObservableStore({})
@ -42,7 +57,7 @@ module.exports = class TransactionController extends EventEmitter {
txHistoryLimit: opts.txHistoryLimit, txHistoryLimit: opts.txHistoryLimit,
getNetwork: this.getNetwork.bind(this), getNetwork: this.getNetwork.bind(this),
}) })
this._mapMethods()
this._onBootCleanUp() this._onBootCleanUp()
this.store = this.txStateManager.store this.store = this.txStateManager.store
@ -68,31 +83,7 @@ module.exports = class TransactionController extends EventEmitter {
this.networkStore.subscribe(() => this._updateMemstore()) this.networkStore.subscribe(() => this._updateMemstore())
this.preferencesStore.subscribe(() => this._updateMemstore()) this.preferencesStore.subscribe(() => this._updateMemstore())
} }
/** @returns {number} the chainId*/
getState () {
return this.memStore.getState()
}
getNetwork () {
return this.networkStore.getState()
}
getSelectedAddress () {
return this.preferencesStore.getState().selectedAddress
}
getUnapprovedTxCount () {
return Object.keys(this.txStateManager.getUnapprovedTxList()).length
}
getPendingTxCount (account) {
return this.txStateManager.getPendingTransactions(account).length
}
getFilteredTxList (opts) {
return this.txStateManager.getFilteredTxList(opts)
}
getChainId () { getChainId () {
const networkState = this.networkStore.getState() const networkState = this.networkStore.getState()
const getChainId = parseInt(networkState) const getChainId = parseInt(networkState)
@ -103,16 +94,27 @@ module.exports = class TransactionController extends EventEmitter {
} }
} }
// Adds a tx to the txlist /** Adds a tx to the txlist */
addTx (txMeta) { addTx (txMeta) {
this.txStateManager.addTx(txMeta) this.txStateManager.addTx(txMeta)
this.emit(`${txMeta.id}:unapproved`, txMeta) this.emit(`${txMeta.id}:unapproved`, txMeta)
} }
/**
wipes the transactions for a given account
@param address {string} - hex string of the from address for txs being removed
*/
wipeTransactions (address) { wipeTransactions (address) {
this.txStateManager.wipeTransactions(address) this.txStateManager.wipeTransactions(address)
} }
/**
add a new unapproved transaction to the pipeline
@returns {promise}
@param txParams {object} - txParams for the transaction
@param opts {object} - with the key origin to put the origin on the txMeta
*/
async newUnapprovedTransaction (txParams, opts = {}) { async newUnapprovedTransaction (txParams, opts = {}) {
log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`) log.debug(`MetaMaskController newUnapprovedTransaction ${JSON.stringify(txParams)}`)
const initialTxMeta = await this.addUnapprovedTransaction(txParams) const initialTxMeta = await this.addUnapprovedTransaction(txParams)
@ -135,6 +137,13 @@ module.exports = class TransactionController extends EventEmitter {
}) })
} }
/**
validates and generates a txMeta with defaults and puts it in txStateManager
store
@returns {txMeta}
*/
async addUnapprovedTransaction (txParams) { async addUnapprovedTransaction (txParams) {
// validate // validate
const normalizedTxParams = txUtils.normalizeTxParams(txParams) const normalizedTxParams = txUtils.normalizeTxParams(txParams)
@ -145,7 +154,7 @@ module.exports = class TransactionController extends EventEmitter {
this.emit('newUnapprovedTx', txMeta) this.emit('newUnapprovedTx', txMeta)
// add default tx params // add default tx params
try { try {
txMeta = await this.addTxDefaults(txMeta) txMeta = await this.addTxGasDefaults(txMeta)
} catch (error) { } catch (error) {
console.log(error) console.log(error)
this.txStateManager.setTxStatusFailed(txMeta.id, error) this.txStateManager.setTxStatusFailed(txMeta.id, error)
@ -157,8 +166,12 @@ module.exports = class TransactionController extends EventEmitter {
return txMeta return txMeta
} }
/**
async addTxDefaults (txMeta) { adds the tx gas defaults: gas && gasPrice
@param txMeta {object} - the txMeta object
@returns {promise} resolves with txMeta
*/
async addTxGasDefaults (txMeta) {
const txParams = txMeta.txParams const txParams = txMeta.txParams
// ensure value // ensure value
txMeta.gasPriceSpecified = Boolean(txParams.gasPrice) txMeta.gasPriceSpecified = Boolean(txParams.gasPrice)
@ -167,11 +180,18 @@ module.exports = class TransactionController extends EventEmitter {
gasPrice = this.getGasPrice ? this.getGasPrice() : await this.query.gasPrice() gasPrice = this.getGasPrice ? this.getGasPrice() : await this.query.gasPrice()
} }
txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16)) txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
txParams.value = txParams.value || '0x0'
// set gasLimit // set gasLimit
return await this.txGasUtil.analyzeGasUsage(txMeta) return await this.txGasUtil.analyzeGasUsage(txMeta)
} }
/**
creates a new txMeta with the same txParams as the original
to allow the user to resign the transaction with a higher gas values
@param originalTxId {number} - the id of the txMeta that
you want to attempt to retry
@return {txMeta}
*/
async retryTransaction (originalTxId) { async retryTransaction (originalTxId) {
const originalTxMeta = this.txStateManager.getTx(originalTxId) const originalTxMeta = this.txStateManager.getTx(originalTxId)
const lastGasPrice = originalTxMeta.txParams.gasPrice const lastGasPrice = originalTxMeta.txParams.gasPrice
@ -185,15 +205,31 @@ module.exports = class TransactionController extends EventEmitter {
return txMeta return txMeta
} }
/**
updates the txMeta in the txStateManager
@param txMeta {object} - the updated txMeta
*/
async updateTransaction (txMeta) { async updateTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction') this.txStateManager.updateTx(txMeta, 'confTx: user updated transaction')
} }
/**
updates and approves the transaction
@param txMeta {object}
*/
async updateAndApproveTransaction (txMeta) { async updateAndApproveTransaction (txMeta) {
this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction') this.txStateManager.updateTx(txMeta, 'confTx: user approved transaction')
await this.approveTransaction(txMeta.id) await this.approveTransaction(txMeta.id)
} }
/**
sets the tx status to approved
auto fills the nonce
signs the transaction
publishes the transaction
if any of these steps fails the tx status will be set to failed
@param txId {number} - the tx's Id
*/
async approveTransaction (txId) { async approveTransaction (txId) {
let nonceLock let nonceLock
try { try {
@ -225,7 +261,11 @@ module.exports = class TransactionController extends EventEmitter {
throw err throw err
} }
} }
/**
adds the chain id and signs the transaction and set the status to signed
@param txId {number} - the tx's Id
@returns - rawTx {string}
*/
async signTransaction (txId) { async signTransaction (txId) {
const txMeta = this.txStateManager.getTx(txId) const txMeta = this.txStateManager.getTx(txId)
// add network/chain id // add network/chain id
@ -241,6 +281,11 @@ module.exports = class TransactionController extends EventEmitter {
return rawTx return rawTx
} }
/**
publishes the raw tx and sets the txMeta to submitted
@param txId {number} - the tx's Id
@param rawTx {string} - the hex string of the serialized signed transaction
*/
async publishTransaction (txId, rawTx) { async publishTransaction (txId, rawTx) {
const txMeta = this.txStateManager.getTx(txId) const txMeta = this.txStateManager.getTx(txId)
txMeta.rawTx = rawTx txMeta.rawTx = rawTx
@ -250,11 +295,19 @@ module.exports = class TransactionController extends EventEmitter {
this.txStateManager.setTxStatusSubmitted(txId) this.txStateManager.setTxStatusSubmitted(txId)
} }
/**
convenience method for the ui thats sets the transaction to rejected
@param txId {number} - the tx's Id
*/
async cancelTransaction (txId) { async cancelTransaction (txId) {
this.txStateManager.setTxStatusRejected(txId) this.txStateManager.setTxStatusRejected(txId)
} }
// receives a txHash records the tx as signed /**
sets the txHas on the txMeta
@param txId {number} - the tx's Id
@param txHash {string} - the hash for the txMeta
*/
setTxHash (txId, txHash) { setTxHash (txId, txHash) {
// Add the tx hash to the persisted meta-tx object // Add the tx hash to the persisted meta-tx object
const txMeta = this.txStateManager.getTx(txId) const txMeta = this.txStateManager.getTx(txId)
@ -265,13 +318,28 @@ module.exports = class TransactionController extends EventEmitter {
// //
// PRIVATE METHODS // PRIVATE METHODS
// //
/** maps methods for convenience*/
_mapMethods () {
/** Returns the state in transaction controller */
this.getState = () => this.memStore.getState()
/** Returns the network number stored in networkStore */
this.getNetwork = () => this.networkStore.getState()
/** Returns the user selected address */
this.getSelectedAddress = () => this.preferencesStore.getState().selectedAddress
/** Returns an array of transactions whos status is unapproved */
this.getUnapprovedTxCount = () => Object.keys(this.txStateManager.getUnapprovedTxList()).length
/** Returns a number that represents how many transactions have the status submitted*/
this.getPendingTxCount = (account) => this.txStateManager.getPendingTransactions(account).length
/** see txStateManager */
this.getFilteredTxList = (opts) => this.txStateManager.getFilteredTxList(opts)
}
_onBootCleanUp () { _onBootCleanUp () {
this.txStateManager.getFilteredTxList({ this.txStateManager.getFilteredTxList({
status: 'unapproved', status: 'unapproved',
loadingDefaults: true, loadingDefaults: true,
}).forEach((tx) => { }).forEach((tx) => {
this.addTxDefaults(tx) this.addTxGasDefaults(tx)
.then((txMeta) => { .then((txMeta) => {
txMeta.loadingDefaults = false txMeta.loadingDefaults = false
this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot') this.txStateManager.updateTx(txMeta, 'transactions: gas estimation for tx on boot')
@ -339,4 +407,4 @@ module.exports = class TransactionController extends EventEmitter {
}) })
this.memStore.updateState({ unapprovedTxs, selectedAddressTxList }) this.memStore.updateState({ unapprovedTxs, selectedAddressTxList })
} }
} }

@ -188,7 +188,7 @@ describe('Transaction Controller', function () {
}) })
describe('#addTxDefaults', function () { describe('#addTxGasDefaults', function () {
it('should add the tx defaults if their are none', function (done) { it('should add the tx defaults if their are none', function (done) {
const txMeta = { const txMeta = {
'txParams': { 'txParams': {
@ -199,7 +199,7 @@ describe('Transaction Controller', function () {
providerResultStub.eth_gasPrice = '4a817c800' providerResultStub.eth_gasPrice = '4a817c800'
providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' } providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }
providerResultStub.eth_estimateGas = '5209' providerResultStub.eth_estimateGas = '5209'
txController.addTxDefaults(txMeta) txController.addTxGasDefaults(txMeta)
.then((txMetaWithDefaults) => { .then((txMetaWithDefaults) => {
assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value') assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value')
assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price') assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price')

Loading…
Cancel
Save