Migrate all tx mutation code out of keyring controller and

Fix up txManager to reflect code review requests
This commit is contained in:
Frances Pangilinan 2016-12-20 13:12:14 -08:00
parent 6e78494846
commit 1ebcbe296b
4 changed files with 70 additions and 53 deletions

View File

@ -101,10 +101,10 @@ txManager.on('update', updateBadge)
function updateBadge () { function updateBadge () {
var label = '' var label = ''
var unconfTxLen = controller.txManager.unconfTxCount var unapprovedTxCount = controller.txManager.unapprovedTxCount
var unconfMsgs = messageManager.unconfirmedMsgs() var unconfMsgs = messageManager.unconfirmedMsgs()
var unconfMsgLen = Object.keys(unconfMsgs).length var unconfMsgLen = Object.keys(unconfMsgs).length
var count = unconfTxLen + unconfMsgLen var count = unapprovedTxCount + unconfMsgLen
if (count) { if (count) {
label = String(count) label = String(count)
} }

View File

@ -1,6 +1,5 @@
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const bip39 = require('bip39') const bip39 = require('bip39')
const Transaction = require('ethereumjs-tx')
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter
const filter = require('promise-filter') const filter = require('promise-filter')
const normalize = require('./lib/sig-util').normalize const normalize = require('./lib/sig-util').normalize
@ -321,28 +320,14 @@ module.exports = class KeyringController extends EventEmitter {
// //
// This method signs tx and returns a promise for // This method signs tx and returns a promise for
// TX Manager to update the state after signing // TX Manager to update the state after signing
signTransaction (txParams, cb) { signTransaction (ethTx, selectedAddress, txId, cb) {
try { try {
const address = normalize(txParams.from) const address = normalize(selectedAddress)
return this.getKeyringForAccount(address) return this.getKeyringForAccount(address)
.then((keyring) => { .then((keyring) => {
// Handle gas pricing return keyring.signTransaction(address, ethTx)
var gasMultiplier = this.configManager.getGasMultiplier() || 1
var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16)
gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10))
txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber())
// normalize values
txParams.to = normalize(txParams.to)
txParams.from = normalize(txParams.from)
txParams.value = normalize(txParams.value)
txParams.data = normalize(txParams.data)
txParams.gasLimit = normalize(txParams.gasLimit || txParams.gas)
txParams.nonce = normalize(txParams.nonce)
const tx = new Transaction(txParams)
return keyring.signTransaction(address, tx)
}).then((tx) => { }).then((tx) => {
return {tx, txParams, cb} this.emit(`${txId}:signed`, {tx, txId, cb})
}) })
} catch (e) { } catch (e) {
cb(e) cb(e)

View File

@ -39,6 +39,8 @@ module.exports = class MetamaskController {
}) })
this.publicConfigStore = this.initPublicConfigStore() this.publicConfigStore = this.initPublicConfigStore()
var currentFiat = this.configManager.getCurrentFiat() || 'USD' var currentFiat = this.configManager.getCurrentFiat() || 'USD'
this.configManager.setCurrentFiat(currentFiat) this.configManager.setCurrentFiat(currentFiat)
this.configManager.updateConversionRate() this.configManager.updateConversionRate()
@ -152,8 +154,8 @@ module.exports = class MetamaskController {
// tx signing // tx signing
approveTransaction: this.newUnsignedTransaction.bind(this), approveTransaction: this.newUnsignedTransaction.bind(this),
signTransaction: (...args) => { signTransaction: (...args) => {
var signedTxPromise = keyringController.signTransaction(...args) this.setupSigningListners(...args)
this.txManager.resolveSignedTransaction(signedTxPromise) this.txManager.formatTxForSigining(...args)
this.sendUpdate() this.sendUpdate()
}, },
@ -232,6 +234,14 @@ module.exports = class MetamaskController {
}) })
} }
setupSigningListners (txParams) {
var txId = txParams.metamaskId
// apply event listeners for signing and formating events
this.txManager.once(`${txId}:formated`, this.keyringController.signTransaction.bind(this.keyringController))
this.keyringController.once(`${txId}:signed`, this.txManager.resolveSignedTransaction.bind(this.txManager))
}
enforceTxValidations (txParams) { enforceTxValidations (txParams) {
if (('value' in txParams) && txParams.value.indexOf('-') === 0) { if (('value' in txParams) && txParams.value.indexOf('-') === 0) {
const msg = `Invalid transaction value of ${txParams.value} not a positive number.` const msg = `Invalid transaction value of ${txParams.value} not a positive number.`

View File

@ -1,8 +1,11 @@
const EventEmitter = require('events') const EventEmitter = require('events')
const extend = require('xtend') const extend = require('xtend')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const Transaction = require('ethereumjs-tx')
const BN = ethUtil.BN
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 normalize = require('./lib/sig-util').normalize
module.exports = class TransactionManager extends EventEmitter { module.exports = class TransactionManager extends EventEmitter {
constructor (opts) { constructor (opts) {
@ -75,7 +78,7 @@ module.exports = class TransactionManager extends EventEmitter {
this._saveTxList(txList) this._saveTxList(txList)
} }
get unconfTxCount () { get unapprovedTxCount () {
return Object.keys(this.getUnapprovedTxList()).length return Object.keys(this.getUnapprovedTxList()).length
} }
@ -128,19 +131,39 @@ module.exports = class TransactionManager extends EventEmitter {
} }
} }
resolveSignedTransaction (txPromise) { // formats txParams so the keyringController can sign it
const self = this formatTxForSigining (txParams, cb) {
var address = txParams.from
var metaTx = this.getTx(txParams.metamaskId)
var gasMultiplier = metaTx.gasMultiplier
var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16)
gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10))
txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber())
txPromise.then(({tx, txParams, cb}) => { // normalize values
// Add the tx hash to the persisted meta-tx object txParams.to = normalize(txParams.to)
var txHash = ethUtil.bufferToHex(tx.hash()) txParams.from = normalize(txParams.from)
txParams.value = normalize(txParams.value)
txParams.data = normalize(txParams.data)
txParams.gasLimit = normalize(txParams.gasLimit || txParams.gas)
txParams.nonce = normalize(txParams.nonce)
const ethTx = new Transaction(txParams)
// this.updateTxParams(txParams.metamaskId, ethTx)
var metaTx = self.getTx(txParams.metamaskId) // listener is assigned in metamaskController
metaTx.hash = txHash this.emit(`${txParams.metamaskId}:formated`, ethTx, address, txParams.metamaskId, cb)
// return raw serialized tx }
var rawTx = ethUtil.bufferToHex(tx.serialize())
cb(null, rawTx) // receives a signed tx object and updates the tx hash
}) // and pass it to the cb to be sent off
resolveSignedTransaction ({tx, txId, cb}) {
// Add the tx hash to the persisted meta-tx object
var txHash = ethUtil.bufferToHex(tx.hash())
var metaTx = this.getTx(txId)
metaTx.hash = txHash
this.updateTx(metaTx)
var rawTx = ethUtil.bufferToHex(tx.serialize())
cb(null, rawTx)
} }
/* /*
@ -176,20 +199,23 @@ module.exports = class TransactionManager extends EventEmitter {
}) })
} }
// should return the status of the tx. // STATUS METHODS
getTxStatus (txId, cb) { // get::set status
// should return the status of the tx.
getTxStatus (txId) {
const txMeta = this.getTx(txId) const txMeta = this.getTx(txId)
return cb ? cb(txMeta.staus) : txMeta.status return txMeta.status
} }
// should update the status of the tx to 'signed'. // should update the status of the tx to 'signed'.
setTxStatusSigned (txId) { setTxStatusSigned (txId) {
this._setTxStatus(txId, 'signed') this._setTxStatus(txId, 'signed')
this.emit('update') this.emit('update')
} }
// should update the status of the tx to 'rejected'. // should update the status of the tx to 'rejected'.
setTxStatusRejected (txId) { setTxStatusRejected (txId) {
this._setTxStatus(txId, 'rejected') this._setTxStatus(txId, 'rejected')
this.emit('update') this.emit('update')
@ -203,7 +229,7 @@ module.exports = class TransactionManager extends EventEmitter {
// use extend to ensure that all fields are filled // use extend to ensure that all fields are filled
updateTxParams (txId, txParams) { updateTxParams (txId, txParams) {
var txMeta = this.getTx(txId) var txMeta = this.getTx(txId)
txMeta.txParams = extend(txMeta, txParams) txMeta.txParams = extend(txMeta.txParams, txParams)
this.updateTx(txMeta) this.updateTx(txMeta)
} }
@ -218,7 +244,7 @@ module.exports = class TransactionManager extends EventEmitter {
if (!txHash) return if (!txHash) return
this.txProviderUtils.query.getTransactionByHash(txHash, (err, txMeta) => { this.txProviderUtils.query.getTransactionByHash(txHash, (err, txMeta) => {
if (err || !txMeta) { if (err || !txMeta) {
tx.err = err || 'Tx could possibly have not submitted' tx.err = err || 'Tx could possibly have not been submitted'
this.updateTx(tx) this.updateTx(tx)
return txMeta ? console.error(err) : console.debug(`txMeta is ${txMeta} for:`, tx) return txMeta ? console.error(err) : console.debug(`txMeta is ${txMeta} for:`, tx)
} }
@ -229,16 +255,7 @@ module.exports = class TransactionManager extends EventEmitter {
}) })
} }
// Private functions // PRIVATE METHODS
// Saves the new/updated txList.
// Function is intended only for internal use
_saveTxList (txList) {
this.txList = txList
this._setTxList(txList)
}
// should return the tx
// Should find the tx in the tx list and // Should find the tx in the tx list and
// update it. // update it.
@ -255,7 +272,12 @@ module.exports = class TransactionManager extends EventEmitter {
this.updateTx(txMeta) this.updateTx(txMeta)
} }
// Saves the new/updated txList.
// Function is intended only for internal use
_saveTxList (txList) {
this.txList = txList
this._setTxList(txList)
}
} }