aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib
diff options
context:
space:
mode:
authorFrances Pangilinan <frankie.diamond@gmail.com>2016-12-15 04:55:41 +0800
committerFrances Pangilinan <frankie.diamond@gmail.com>2016-12-15 04:55:41 +0800
commit090935f90aa3c2589fee7bc038c8f4fcf77da03c (patch)
tree82a21bd7d0df26d6de637892cbd9322d52b7785b /app/scripts/lib
parent9e3fa3cfba20299413df87d18158180c7798d2ac (diff)
downloadtangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar.gz
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar.bz2
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar.lz
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar.xz
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.tar.zst
tangerine-wallet-browser-090935f90aa3c2589fee7bc038c8f4fcf77da03c.zip
Create a TxManager
Diffstat (limited to 'app/scripts/lib')
-rw-r--r--app/scripts/lib/config-manager.js51
-rw-r--r--app/scripts/lib/idStore.js13
-rw-r--r--app/scripts/lib/provider-utils.js106
3 files changed, 118 insertions, 52 deletions
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index 59cc2b63c..913a76a6e 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -209,61 +209,12 @@ ConfigManager.prototype.getTxList = function () {
}
}
-ConfigManager.prototype.unconfirmedTxs = function () {
- var transactions = this.getTxList()
- return transactions.filter(tx => tx.status === 'unconfirmed')
- .reduce((result, tx) => { result[tx.id] = tx; return result }, {})
-}
-
-ConfigManager.prototype._saveTxList = function (txList) {
+ConfigManager.prototype.setTxList = function (txList) {
var data = this.migrator.getData()
data.transactions = txList
this.setData(data)
}
-ConfigManager.prototype.addTx = function (tx) {
- var transactions = this.getTxList()
- while (transactions.length > this.txLimit - 1) {
- transactions.shift()
- }
- transactions.push(tx)
- this._saveTxList(transactions)
-}
-
-ConfigManager.prototype.getTx = function (txId) {
- var transactions = this.getTxList()
- var matching = transactions.filter(tx => tx.id === txId)
- return matching.length > 0 ? matching[0] : null
-}
-
-ConfigManager.prototype.confirmTx = function (txId) {
- this._setTxStatus(txId, 'confirmed')
-}
-
-ConfigManager.prototype.rejectTx = function (txId) {
- this._setTxStatus(txId, 'rejected')
-}
-
-ConfigManager.prototype._setTxStatus = function (txId, status) {
- var tx = this.getTx(txId)
- tx.status = status
- this.updateTx(tx)
-}
-
-ConfigManager.prototype.updateTx = function (tx) {
- var transactions = this.getTxList()
- var found, index
- transactions.forEach((otherTx, i) => {
- if (otherTx.id === tx.id) {
- found = true
- index = i
- }
- })
- if (found) {
- transactions[index] = tx
- }
- this._saveTxList(transactions)
-}
// wallet nickname methods
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index d36504f13..71bee8026 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -13,6 +13,8 @@ const autoFaucet = require('./auto-faucet')
const messageManager = require('./message-manager')
const DEFAULT_RPC = 'https://testrpc.metamask.io/'
const IdManagement = require('./id-management')
+const TxManager = require('../transaction-manager')
+
module.exports = IdentityStore
@@ -36,6 +38,11 @@ function IdentityStore (opts = {}) {
}
// not part of serilized metamask state - only kept in memory
+ this.txManager = new TxManager({
+ TxListFromStore: opts.configManager.getTxList(),
+ setTxList: opts.configManager.setTxList.bind(opts.configManager),
+ txLimit: 40,
+ })
this._unconfTxCbs = {}
this._unconfMsgCbs = {}
}
@@ -87,6 +94,7 @@ IdentityStore.prototype.recoverFromSeed = function (password, seed, cb) {
IdentityStore.prototype.setStore = function (store) {
this._ethStore = store
+ this.txManager.setProvider(this._ethStore._query.currentProvider)
}
IdentityStore.prototype.clearSeedWordCache = function (cb) {
@@ -97,14 +105,15 @@ IdentityStore.prototype.clearSeedWordCache = function (cb) {
IdentityStore.prototype.getState = function () {
const configManager = this.configManager
+ const TxManager = this.txManager
var seedWords = this.getSeedIfUnlocked()
return clone(extend(this._currentState, {
isInitialized: !!configManager.getWallet() && !seedWords,
isUnlocked: this._isUnlocked(),
seedWords: seedWords,
isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
- unconfTxs: configManager.unconfirmedTxs(),
- transactions: configManager.getTxList(),
+ unconfTxs: TxManager.getUnapprovedTxList(),
+ transactions: TxManager.getTxList(),
unconfMsgs: messageManager.unconfirmedMsgs(),
messages: messageManager.getMsgList(),
selectedAddress: configManager.getSelectedAccount(),
diff --git a/app/scripts/lib/provider-utils.js b/app/scripts/lib/provider-utils.js
new file mode 100644
index 000000000..d1678c964
--- /dev/null
+++ b/app/scripts/lib/provider-utils.js
@@ -0,0 +1,106 @@
+const async = require('async')
+const EthQuery = require('eth-query')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const ethBinToOps = require('eth-bin-to-ops')
+
+module.exports = class txProviderUtils {
+ constructor (provider) {
+ this.provider = provider
+ this.query = new EthQuery(provider)
+ }
+ analyzeGasUsage (txData, cb) {
+ var self = this
+ this.query.getBlockByNumber('latest', true, (err, block) => {
+ if (err) return cb(err)
+ async.waterfall([
+ self.estimateTxGas.bind(self, txData, block.gasLimit),
+ self.checkForTxGasError.bind(self, txData),
+ self.setTxGas.bind(self, txData, block.gasLimit),
+ ], cb)
+ })
+ }
+
+ // perform static analyis on the target contract code
+ analyzeForDelegateCall (txParams, cb) {
+ if (txParams.to) {
+ this.query.getCode(txParams.to, function (err, result) {
+ if (err) return cb(err)
+
+ var code = ethUtil.toBuffer(result)
+ if (code !== '0x') {
+ var ops = ethBinToOps(code)
+ var containsDelegateCall = ops.some((op) => op.name === 'DELEGATECALL')
+ cb(containsDelegateCall)
+ } else {
+ cb()
+ }
+ })
+ } else {
+ cb()
+ }
+ }
+
+ estimateTxGas (txData, blockGasLimitHex, cb) {
+ const txParams = txData.txParams
+ // check if gasLimit is already specified
+ txData.gasLimitSpecified = Boolean(txParams.gas)
+ // if not, fallback to block gasLimit
+ if (!txData.gasLimitSpecified) {
+ txParams.gas = blockGasLimitHex
+ }
+ // run tx, see if it will OOG
+ this.query.estimateGas(txParams, cb)
+ }
+
+ checkForTxGasError (txData, estimatedGasHex, cb) {
+ txData.estimatedGas = estimatedGasHex
+ // all gas used - must be an error
+ if (estimatedGasHex === txData.txParams.gas) {
+ txData.simulationFails = true
+ }
+ cb()
+ }
+
+ handleFork (block) {
+
+ }
+
+ setTxGas (txData, blockGasLimitHex, cb) {
+ const txParams = txData.txParams
+ // if OOG, nothing more to do
+ 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(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
+ }
+
+ addGasBuffer (gas) {
+ const gasBuffer = new BN('100000', 10)
+ const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
+ const correct = bnGas.add(gasBuffer)
+ return ethUtil.addHexPrefix(correct.toString(16))
+ }
+}