mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Adds a transactionCategory to txMeta for use in UI (#6567)
* Adds a transactionCategory to txMeta for use in UI * Update transaction controller and tx-gas-util documentation on new code param in multiple functions.
This commit is contained in:
parent
56ed189aeb
commit
ef8a07c2ce
@ -3,6 +3,17 @@ const ObservableStore = require('obs-store')
|
|||||||
const ethUtil = require('ethereumjs-util')
|
const ethUtil = require('ethereumjs-util')
|
||||||
const Transaction = require('ethereumjs-tx')
|
const Transaction = require('ethereumjs-tx')
|
||||||
const EthQuery = require('ethjs-query')
|
const EthQuery = require('ethjs-query')
|
||||||
|
const abi = require('human-standard-token-abi')
|
||||||
|
const abiDecoder = require('abi-decoder')
|
||||||
|
abiDecoder.addABI(abi)
|
||||||
|
const {
|
||||||
|
TOKEN_METHOD_APPROVE,
|
||||||
|
TOKEN_METHOD_TRANSFER,
|
||||||
|
TOKEN_METHOD_TRANSFER_FROM,
|
||||||
|
SEND_ETHER_ACTION_KEY,
|
||||||
|
DEPLOY_CONTRACT_ACTION_KEY,
|
||||||
|
CONTRACT_INTERACTION_KEY,
|
||||||
|
} = require('../../../../ui/app/helpers/constants/transactions.js')
|
||||||
const TransactionStateManager = require('./tx-state-manager')
|
const TransactionStateManager = require('./tx-state-manager')
|
||||||
const TxGasUtil = require('./tx-gas-utils')
|
const TxGasUtil = require('./tx-gas-utils')
|
||||||
const PendingTransactionTracker = require('./pending-tx-tracker')
|
const PendingTransactionTracker = require('./pending-tx-tracker')
|
||||||
@ -180,9 +191,11 @@ class TransactionController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
txUtils.validateTxParams(normalizedTxParams)
|
txUtils.validateTxParams(normalizedTxParams)
|
||||||
// construct txMeta
|
// construct txMeta
|
||||||
|
const { transactionCategory, code } = await this._determineTransactionCategory(txParams)
|
||||||
let txMeta = this.txStateManager.generateTxMeta({
|
let txMeta = this.txStateManager.generateTxMeta({
|
||||||
txParams: normalizedTxParams,
|
txParams: normalizedTxParams,
|
||||||
type: TRANSACTION_TYPE_STANDARD,
|
type: TRANSACTION_TYPE_STANDARD,
|
||||||
|
transactionCategory,
|
||||||
})
|
})
|
||||||
this.addTx(txMeta)
|
this.addTx(txMeta)
|
||||||
this.emit('newUnapprovedTx', txMeta)
|
this.emit('newUnapprovedTx', txMeta)
|
||||||
@ -191,7 +204,7 @@ class TransactionController extends EventEmitter {
|
|||||||
// check whether recipient account is blacklisted
|
// check whether recipient account is blacklisted
|
||||||
recipientBlacklistChecker.checkAccount(txMeta.metamaskNetworkId, normalizedTxParams.to)
|
recipientBlacklistChecker.checkAccount(txMeta.metamaskNetworkId, normalizedTxParams.to)
|
||||||
// add default tx params
|
// add default tx params
|
||||||
txMeta = await this.addTxGasDefaults(txMeta)
|
txMeta = await this.addTxGasDefaults(txMeta, code)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.warn(error)
|
log.warn(error)
|
||||||
txMeta.loadingDefaults = false
|
txMeta.loadingDefaults = false
|
||||||
@ -211,7 +224,7 @@ class TransactionController extends EventEmitter {
|
|||||||
@param txMeta {Object} - the txMeta object
|
@param txMeta {Object} - the txMeta object
|
||||||
@returns {Promise<object>} resolves with txMeta
|
@returns {Promise<object>} resolves with txMeta
|
||||||
*/
|
*/
|
||||||
async addTxGasDefaults (txMeta) {
|
async addTxGasDefaults (txMeta, code) {
|
||||||
const txParams = txMeta.txParams
|
const txParams = txMeta.txParams
|
||||||
// ensure value
|
// ensure value
|
||||||
txParams.value = txParams.value ? ethUtil.addHexPrefix(txParams.value) : '0x0'
|
txParams.value = txParams.value ? ethUtil.addHexPrefix(txParams.value) : '0x0'
|
||||||
@ -222,7 +235,7 @@ class TransactionController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
|
txParams.gasPrice = ethUtil.addHexPrefix(gasPrice.toString(16))
|
||||||
// set gasLimit
|
// set gasLimit
|
||||||
return await this.txGasUtil.analyzeGasUsage(txMeta)
|
return await this.txGasUtil.analyzeGasUsage(txMeta, code)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -555,6 +568,42 @@ class TransactionController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a "type" for a transaction out of the following list: simpleSend, tokenTransfer, tokenApprove,
|
||||||
|
contractDeployment, contractMethodCall
|
||||||
|
*/
|
||||||
|
async _determineTransactionCategory (txParams) {
|
||||||
|
const { data, to } = txParams
|
||||||
|
const { name } = data && abiDecoder.decodeMethod(data) || {}
|
||||||
|
const tokenMethodName = [
|
||||||
|
TOKEN_METHOD_APPROVE,
|
||||||
|
TOKEN_METHOD_TRANSFER,
|
||||||
|
TOKEN_METHOD_TRANSFER_FROM,
|
||||||
|
].find(tokenMethodName => tokenMethodName === name && name.toLowerCase())
|
||||||
|
|
||||||
|
let result
|
||||||
|
let code
|
||||||
|
if (!txParams.data) {
|
||||||
|
result = SEND_ETHER_ACTION_KEY
|
||||||
|
} else if (tokenMethodName) {
|
||||||
|
result = tokenMethodName
|
||||||
|
} else if (!to) {
|
||||||
|
result = DEPLOY_CONTRACT_ACTION_KEY
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
code = await this.query.getCode(to)
|
||||||
|
} catch (e) {
|
||||||
|
log.warn(e)
|
||||||
|
}
|
||||||
|
// For an address with no code, geth will return '0x', and ganache-core v2.2.1 will return '0x0'
|
||||||
|
const codeIsEmpty = !code || code === '0x' || code === '0x0'
|
||||||
|
|
||||||
|
result = codeIsEmpty ? SEND_ETHER_ACTION_KEY : CONTRACT_INTERACTION_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
return { transactionCategory: result, code }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
Sets other txMeta statuses to dropped if the txMeta that has been confirmed has other transactions
|
||||||
in the list have the same nonce
|
in the list have the same nonce
|
||||||
|
@ -4,6 +4,7 @@ const {
|
|||||||
BnMultiplyByFraction,
|
BnMultiplyByFraction,
|
||||||
bnToHex,
|
bnToHex,
|
||||||
} = require('../../lib/util')
|
} = require('../../lib/util')
|
||||||
|
const log = require('loglevel')
|
||||||
const { addHexPrefix } = require('ethereumjs-util')
|
const { addHexPrefix } = require('ethereumjs-util')
|
||||||
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
|
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
|
||||||
|
|
||||||
@ -24,14 +25,16 @@ class TxGasUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
@param txMeta {Object} - the txMeta object
|
@param txMeta {Object} - the txMeta object
|
||||||
|
@param code {string} - the code at the txs address, as returned by this.query.getCode(to)
|
||||||
@returns {object} the txMeta object with the gas written to the txParams
|
@returns {object} the txMeta object with the gas written to the txParams
|
||||||
*/
|
*/
|
||||||
async analyzeGasUsage (txMeta) {
|
async analyzeGasUsage (txMeta, code) {
|
||||||
const block = await this.query.getBlockByNumber('latest', false)
|
const block = await this.query.getBlockByNumber('latest', false)
|
||||||
let estimatedGasHex
|
let estimatedGasHex
|
||||||
try {
|
try {
|
||||||
estimatedGasHex = await this.estimateTxGas(txMeta, block.gasLimit)
|
estimatedGasHex = await this.estimateTxGas(txMeta, block.gasLimit, code)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
log.warn(err)
|
||||||
txMeta.simulationFails = {
|
txMeta.simulationFails = {
|
||||||
reason: err.message,
|
reason: err.message,
|
||||||
errorKey: err.errorKey,
|
errorKey: err.errorKey,
|
||||||
@ -52,9 +55,10 @@ class TxGasUtil {
|
|||||||
Estimates the tx's gas usage
|
Estimates the tx's gas usage
|
||||||
@param txMeta {Object} - the txMeta object
|
@param txMeta {Object} - the txMeta object
|
||||||
@param blockGasLimitHex {string} - hex string of the block's gas limit
|
@param blockGasLimitHex {string} - hex string of the block's gas limit
|
||||||
|
@param code {string} - the code at the txs address, as returned by this.query.getCode(to)
|
||||||
@returns {string} the estimated gas limit as a hex string
|
@returns {string} the estimated gas limit as a hex string
|
||||||
*/
|
*/
|
||||||
async estimateTxGas (txMeta, blockGasLimitHex) {
|
async estimateTxGas (txMeta, blockGasLimitHex, code) {
|
||||||
const txParams = txMeta.txParams
|
const txParams = txMeta.txParams
|
||||||
|
|
||||||
// check if gasLimit is already specified
|
// check if gasLimit is already specified
|
||||||
@ -70,7 +74,6 @@ class TxGasUtil {
|
|||||||
|
|
||||||
// see if we can set the gas based on the recipient
|
// see if we can set the gas based on the recipient
|
||||||
if (hasRecipient) {
|
if (hasRecipient) {
|
||||||
const code = await this.query.getCode(recipient)
|
|
||||||
// For an address with no code, geth will return '0x', and ganache-core v2.2.1 will return '0x0'
|
// For an address with no code, geth will return '0x', and ganache-core v2.2.1 will return '0x0'
|
||||||
const codeIsEmpty = !code || code === '0x' || code === '0x0'
|
const codeIsEmpty = !code || code === '0x' || code === '0x0'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user