Flattened addTx async methods

feature/default_network_editable
Dan Finlay 8 years ago
parent ff3f6cc36a
commit 5bf1018d75
  1. 171
      app/scripts/keyring-controller.js
  2. 2
      package.json

@ -1,11 +1,10 @@
const async = require('async') const async = require('async')
const bind = require('ap').partial
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const EthQuery = require('eth-query') const EthQuery = require('eth-query')
const bip39 = require('bip39') const bip39 = require('bip39')
const Transaction = require('ethereumjs-tx') const Transaction = require('ethereumjs-tx')
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter
const filter = require('promise-filter')
const normalize = require('./lib/sig-util').normalize const normalize = require('./lib/sig-util').normalize
const encryptor = require('./lib/encryptor') const encryptor = require('./lib/encryptor')
const messageManager = require('./lib/message-manager') const messageManager = require('./lib/message-manager')
@ -341,7 +340,6 @@ module.exports = class KeyringController extends EventEmitter {
// Estimates gas and other preparatory steps. // Estimates gas and other preparatory steps.
// Caches the requesting Dapp's callback, `onTxDoneCb`, for resolution later. // Caches the requesting Dapp's callback, `onTxDoneCb`, for resolution later.
addUnconfirmedTransaction (txParams, onTxDoneCb, cb) { addUnconfirmedTransaction (txParams, onTxDoneCb, cb) {
var self = this
const configManager = this.configManager const configManager = this.configManager
// create txData obj with parameters and meta data // create txData obj with parameters and meta data
@ -358,7 +356,6 @@ module.exports = class KeyringController extends EventEmitter {
metamaskNetworkId: this.getNetwork(), metamaskNetworkId: this.getNetwork(),
} }
// keep the onTxDoneCb around for after approval/denial (requires user interaction) // keep the onTxDoneCb around for after approval/denial (requires user interaction)
// This onTxDoneCb fires completion to the Dapp's write operation. // This onTxDoneCb fires completion to the Dapp's write operation.
this._unconfTxCbs[txId] = onTxDoneCb this._unconfTxCbs[txId] = onTxDoneCb
@ -367,81 +364,80 @@ module.exports = class KeyringController extends EventEmitter {
var query = new EthQuery(provider) var query = new EthQuery(provider)
// calculate metadata for tx // calculate metadata for tx
async.parallel([ this.analyzeTxGasUsage(query, txData, this.txDidComplete.bind(this, txData, cb))
analyzeGasUsage, }
], didComplete)
estimateTxGas (query, txData, blockGasLimitHex, cb) {
function analyzeGasUsage (cb) { const txParams = txData.txParams
query.getBlockByNumber('latest', true, function (err, block) { // check if gasLimit is already specified
if (err) return cb(err) txData.gasLimitSpecified = Boolean(txParams.gas)
async.waterfall([ // if not, fallback to block gasLimit
bind(estimateGas, query, txData, block.gasLimit), if (!txData.gasLimitSpecified) {
bind(checkForGasError, txData), txParams.gas = blockGasLimitHex
bind(setTxGas, txData, block.gasLimit),
], cb)
})
} }
// run tx, see if it will OOG
query.estimateGas(txParams, cb)
}
function estimateGas (query, txData, blockGasLimitHex, cb) { checkForTxGasError (txData, estimatedGasHex, cb) {
const txParams = txData.txParams txData.estimatedGas = estimatedGasHex
// check if gasLimit is already specified // all gas used - must be an error
txData.gasLimitSpecified = Boolean(txParams.gas) if (estimatedGasHex === txData.txParams.gas) {
// if not, fallback to block gasLimit txData.simulationFails = true
if (!txData.gasLimitSpecified) {
txParams.gas = blockGasLimitHex
}
// run tx, see if it will OOG
query.estimateGas(txParams, cb)
} }
cb()
}
function checkForGasError (txData, estimatedGasHex, cb) { setTxGas (txData, blockGasLimitHex, cb) {
txData.estimatedGas = estimatedGasHex const txParams = txData.txParams
// all gas used - must be an error // if OOG, nothing more to do
if (estimatedGasHex === txData.txParams.gas) { if (txData.simulationFails) {
txData.simulationFails = true
}
cb() cb()
return
} }
// if gasLimit was specified and doesnt OOG,
function setTxGas (txData, blockGasLimitHex, cb) { // use original specified amount
const txParams = txData.txParams if (txData.gasLimitSpecified) {
// if OOG, nothing more to do txData.estimatedGas = txParams.gas
if (txData.simulationFails) {
cb()
return
}
// if gasLimit was specified and doesnt OOG,
// use original specified amount
if (txData.gasLimitSpecified) {
txData.estimatedGas = txParams.gas
cb()
return
}
// if gasLimit not originally specified,
// try adding an additional gas buffer to our estimation for safety
const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16)
const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16)
const estimationWithBuffer = new BN(self.addGasBuffer(estimatedGasBn), 16)
// added gas buffer is too high
if (estimationWithBuffer.gt(blockGasLimitBn)) {
txParams.gas = txData.estimatedGas
// added gas buffer is safe
} else {
const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer)
txParams.gas = gasWithBufferHex
}
cb() cb()
return return
} }
// if gasLimit not originally specified,
// try adding an additional gas buffer to our estimation for safety
const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16)
const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16)
const estimationWithBuffer = new BN(this.addGasBuffer(estimatedGasBn), 16)
// added gas buffer is too high
if (estimationWithBuffer.gt(blockGasLimitBn)) {
txParams.gas = txData.estimatedGas
// added gas buffer is safe
} else {
const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer)
txParams.gas = gasWithBufferHex
}
cb()
return
}
function didComplete (err) { txDidComplete (txData, cb, err) {
if (err) return cb(err)
const configManager = this.configManager
configManager.addTx(txData)
// signal update
this.emit('update')
// signal completion of add tx
cb(null, txData)
}
analyzeTxGasUsage (query, txData, cb) {
query.getBlockByNumber('latest', true, (err, block) => {
if (err) return cb(err) if (err) return cb(err)
configManager.addTx(txData) async.waterfall([
// signal update this.estimateTxGas.bind(this, query, txData, block.gasLimit),
self.emit('update') this.checkForTxGasError.bind(this, txData),
// signal completion of add tx this.setTxGas.bind(this, txData, block.gasLimit),
cb(null, txData) ], cb)
} })
} }
// Cancel Transaction // Cancel Transaction
@ -488,6 +484,7 @@ module.exports = class KeyringController extends EventEmitter {
delete this._unconfTxCbs[txId] delete this._unconfTxCbs[txId]
this.emit('update') this.emit('update')
} }
signTransaction (txParams, cb) { signTransaction (txParams, cb) {
try { try {
const address = normalize(txParams.from) const address = normalize(txParams.from)
@ -828,28 +825,23 @@ module.exports = class KeyringController extends EventEmitter {
// the specified `address` if one exists. // the specified `address` if one exists.
getKeyringForAccount (address) { getKeyringForAccount (address) {
const hexed = normalize(address) const hexed = normalize(address)
return new Promise((resolve, reject) => {
// Get all the keyrings, and associate them with their account list:
Promise.all(this.keyrings.map((keyring) => {
const accounts = keyring.getAccounts()
return Promise.all({
keyring,
accounts,
})
}))
// Find the keyring with the matching account and return it: return Promise.all(this.keyrings.map((keyring) => {
.then((result) => { return Promise.all([
const match = result.find((candidate) => { keyring,
return candidate.accounts.map(normalize).includes(hexed) keyring.getAccounts(),
}) ])
if (match) { }))
resolve(match.keyring) .then(filter((candidate) => {
} else { const accounts = candidate[1].map(normalize)
reject('No keyring found for the requested account.') return accounts.includes(hexed)
} }))
}) .then((winners) => {
if (winners && winners.length > 0) {
return winners[0][0]
} else {
throw new Error('No keyring found for the requested account.')
}
}) })
} }
@ -888,4 +880,5 @@ module.exports = class KeyringController extends EventEmitter {
} }
function noop () {} function noop () {}

@ -33,7 +33,6 @@
] ]
}, },
"dependencies": { "dependencies": {
"ap": "^0.2.0",
"async": "^1.5.2", "async": "^1.5.2",
"bip39": "^2.2.0", "bip39": "^2.2.0",
"browserify-derequire": "^0.9.4", "browserify-derequire": "^0.9.4",
@ -67,6 +66,7 @@
"pojo-migrator": "^2.1.0", "pojo-migrator": "^2.1.0",
"polyfill-crypto.getrandomvalues": "^1.0.0", "polyfill-crypto.getrandomvalues": "^1.0.0",
"post-message-stream": "^1.0.0", "post-message-stream": "^1.0.0",
"promise-filter": "^1.1.0",
"pumpify": "^1.3.4", "pumpify": "^1.3.4",
"qrcode-npm": "0.0.3", "qrcode-npm": "0.0.3",
"react": "^15.0.2", "react": "^15.0.2",

Loading…
Cancel
Save