mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-10-22 19:26:13 +02:00
meta - transactions - code clean up and jsDoc
This commit is contained in:
parent
3aaa28531e
commit
88f4212363
@ -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')
|
||||||
|
@ -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…
Reference in New Issue
Block a user