mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
meta - transactions - create a transactions dir in controller and move relevant files into it
This commit is contained in:
parent
2b787f2833
commit
2d7c3c2b00
@ -3,11 +3,11 @@ 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 TransactionStateManager = require('../lib/tx-state-manager')
|
const TransactionStateManager = require('./tx-state-manager')
|
||||||
const TxGasUtil = require('../lib/tx-gas-utils')
|
const TxGasUtil = require('./tx-gas-utils')
|
||||||
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
|
const PendingTransactionTracker = require('./pending-tx-tracker')
|
||||||
const NonceTracker = require('../lib/nonce-tracker')
|
const NonceTracker = require('./nonce-tracker')
|
||||||
|
const txUtils = require('./lib/util')
|
||||||
/*
|
/*
|
||||||
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
|
||||||
@ -185,8 +185,8 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
|
|
||||||
async addUnapprovedTransaction (txParams) {
|
async addUnapprovedTransaction (txParams) {
|
||||||
// validate
|
// validate
|
||||||
const normalizedTxParams = this._normalizeTxParams(txParams)
|
const normalizedTxParams = txUtils.normalizeTxParams(txParams)
|
||||||
this._validateTxParams(normalizedTxParams)
|
txUtils.validateTxParams(normalizedTxParams)
|
||||||
// construct txMeta
|
// construct txMeta
|
||||||
let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams })
|
let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams })
|
||||||
this.addTx(txMeta)
|
this.addTx(txMeta)
|
||||||
@ -314,60 +314,6 @@ module.exports = class TransactionController extends EventEmitter {
|
|||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
//
|
//
|
||||||
|
|
||||||
_normalizeTxParams (txParams) {
|
|
||||||
// functions that handle normalizing of that key in txParams
|
|
||||||
const whiteList = {
|
|
||||||
from: from => ethUtil.addHexPrefix(from).toLowerCase(),
|
|
||||||
to: to => ethUtil.addHexPrefix(txParams.to).toLowerCase(),
|
|
||||||
nonce: nonce => ethUtil.addHexPrefix(nonce),
|
|
||||||
value: value => ethUtil.addHexPrefix(value),
|
|
||||||
data: data => ethUtil.addHexPrefix(data),
|
|
||||||
gas: gas => ethUtil.addHexPrefix(gas),
|
|
||||||
gasPrice: gasPrice => ethUtil.addHexPrefix(gasPrice),
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply only keys in the whiteList
|
|
||||||
const normalizedTxParams = {}
|
|
||||||
Object.keys(whiteList).forEach((key) => {
|
|
||||||
if (txParams[key]) normalizedTxParams[key] = whiteList[key](txParams[key])
|
|
||||||
})
|
|
||||||
|
|
||||||
return normalizedTxParams
|
|
||||||
}
|
|
||||||
|
|
||||||
_validateTxParams (txParams) {
|
|
||||||
this._validateFrom(txParams)
|
|
||||||
this._validateRecipient(txParams)
|
|
||||||
if ('value' in txParams) {
|
|
||||||
const value = txParams.value.toString()
|
|
||||||
if (value.includes('-')) {
|
|
||||||
throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.includes('.')) {
|
|
||||||
throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_validateFrom (txParams) {
|
|
||||||
if ( !(typeof txParams.from === 'string') ) throw new Error(`Invalid from address ${txParams.from} not a string`)
|
|
||||||
if (!ethUtil.isValidAddress(txParams.from)) throw new Error('Invalid from address')
|
|
||||||
}
|
|
||||||
|
|
||||||
_validateRecipient (txParams) {
|
|
||||||
if (txParams.to === '0x' || txParams.to === null ) {
|
|
||||||
if (txParams.data) {
|
|
||||||
delete txParams.to
|
|
||||||
} else {
|
|
||||||
throw new Error('Invalid recipient address')
|
|
||||||
}
|
|
||||||
} else if ( txParams.to !== undefined && !ethUtil.isValidAddress(txParams.to) ) {
|
|
||||||
throw new Error('Invalid recipient address')
|
|
||||||
}
|
|
||||||
return txParams
|
|
||||||
}
|
|
||||||
|
|
||||||
_markNonceDuplicatesDropped (txId) {
|
_markNonceDuplicatesDropped (txId) {
|
||||||
this.txStateManager.setTxStatusConfirmed(txId)
|
this.txStateManager.setTxStatusConfirmed(txId)
|
||||||
// get the confirmed transactions nonce and from address
|
// get the confirmed transactions nonce and from address
|
66
app/scripts/controllers/transactions/lib/util.js
Normal file
66
app/scripts/controllers/transactions/lib/util.js
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
const {
|
||||||
|
addHexPrefix,
|
||||||
|
isValidAddress,
|
||||||
|
} = require('ethereumjs-util')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
normalizeTxParams,
|
||||||
|
validateTxParams,
|
||||||
|
validateFrom,
|
||||||
|
validateRecipient
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function normalizeTxParams (txParams) {
|
||||||
|
// functions that handle normalizing of that key in txParams
|
||||||
|
const whiteList = {
|
||||||
|
from: from => addHexPrefix(from).toLowerCase(),
|
||||||
|
to: to => addHexPrefix(txParams.to).toLowerCase(),
|
||||||
|
nonce: nonce => addHexPrefix(nonce),
|
||||||
|
value: value => addHexPrefix(value),
|
||||||
|
data: data => addHexPrefix(data),
|
||||||
|
gas: gas => addHexPrefix(gas),
|
||||||
|
gasPrice: gasPrice => addHexPrefix(gasPrice),
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply only keys in the whiteList
|
||||||
|
const normalizedTxParams = {}
|
||||||
|
Object.keys(whiteList).forEach((key) => {
|
||||||
|
if (txParams[key]) normalizedTxParams[key] = whiteList[key](txParams[key])
|
||||||
|
})
|
||||||
|
|
||||||
|
return normalizedTxParams
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateTxParams (txParams) {
|
||||||
|
validateFrom(txParams)
|
||||||
|
validateRecipient(txParams)
|
||||||
|
if ('value' in txParams) {
|
||||||
|
const value = txParams.value.toString()
|
||||||
|
if (value.includes('-')) {
|
||||||
|
throw new Error(`Invalid transaction value of ${txParams.value} not a positive number.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.includes('.')) {
|
||||||
|
throw new Error(`Invalid transaction value of ${txParams.value} number must be in wei`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateFrom (txParams) {
|
||||||
|
if ( !(typeof txParams.from === 'string') ) throw new Error(`Invalid from address ${txParams.from} not a string`)
|
||||||
|
if (!isValidAddress(txParams.from)) throw new Error('Invalid from address')
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateRecipient (txParams) {
|
||||||
|
if (txParams.to === '0x' || txParams.to === null ) {
|
||||||
|
if (txParams.data) {
|
||||||
|
delete txParams.to
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid recipient address')
|
||||||
|
}
|
||||||
|
} else if ( txParams.to !== undefined && !isValidAddress(txParams.to) ) {
|
||||||
|
throw new Error('Invalid recipient address')
|
||||||
|
}
|
||||||
|
return txParams
|
||||||
|
}
|
@ -3,7 +3,7 @@ const {
|
|||||||
hexToBn,
|
hexToBn,
|
||||||
BnMultiplyByFraction,
|
BnMultiplyByFraction,
|
||||||
bnToHex,
|
bnToHex,
|
||||||
} = require('./util')
|
} = require('../../lib/util')
|
||||||
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.
|
||||||
|
|
@ -1,9 +1,9 @@
|
|||||||
const extend = require('xtend')
|
const extend = require('xtend')
|
||||||
const EventEmitter = require('events')
|
const EventEmitter = require('events')
|
||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const createId = require('./random-id')
|
const createId = require('../../lib/random-id')
|
||||||
const ethUtil = require('ethereumjs-util')
|
const ethUtil = require('ethereumjs-util')
|
||||||
const txStateHistoryHelper = require('./tx-state-history-helper')
|
const txStateHistoryHelper = require('./lib/tx-state-history-helper')
|
||||||
|
|
||||||
// STATUS METHODS
|
// STATUS METHODS
|
||||||
// statuses:
|
// statuses:
|
||||||
@ -92,7 +92,9 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
|||||||
// or rejected tx's.
|
// or rejected tx's.
|
||||||
// not tx's that are pending or unapproved
|
// not tx's that are pending or unapproved
|
||||||
if (txCount > txHistoryLimit - 1) {
|
if (txCount > txHistoryLimit - 1) {
|
||||||
let index = transactions.findIndex((metaTx) => metaTx.status === 'confirmed' || metaTx.status === 'rejected')
|
let index = transactions.findIndex((metaTx) => {
|
||||||
|
return this.getFinalStates().includes(metaTx.status)
|
||||||
|
})
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
transactions.splice(index, 1)
|
transactions.splice(index, 1)
|
||||||
}
|
}
|
||||||
@ -258,6 +260,16 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
|||||||
this._setTxStatus(txId, 'failed')
|
this._setTxStatus(txId, 'failed')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns an array of states that can be considered final
|
||||||
|
getFinalStates () {
|
||||||
|
return [
|
||||||
|
'rejected', // the user has responded no!
|
||||||
|
'confirmed', // the tx has been included in a block.
|
||||||
|
'failed', // the tx failed for some reason, included on tx data.
|
||||||
|
'dropped', // the tx nonce was already used
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
wipeTransactions (address) {
|
wipeTransactions (address) {
|
||||||
// network only tx
|
// network only tx
|
||||||
const txs = this.getFullTxList()
|
const txs = this.getFullTxList()
|
||||||
@ -273,9 +285,8 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
|||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
//
|
//
|
||||||
|
|
||||||
// Should find the tx in the tx list and
|
// STATUS METHODS
|
||||||
// update it.
|
// statuses:
|
||||||
// should set the status in txData
|
|
||||||
// - `'unapproved'` the user has not responded
|
// - `'unapproved'` the user has not responded
|
||||||
// - `'rejected'` the user has responded no!
|
// - `'rejected'` the user has responded no!
|
||||||
// - `'approved'` the user has approved the tx
|
// - `'approved'` the user has approved the tx
|
||||||
@ -283,6 +294,7 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
|||||||
// - `'submitted'` the tx is sent to a server
|
// - `'submitted'` the tx is sent to a server
|
||||||
// - `'confirmed'` the tx has been included in a block.
|
// - `'confirmed'` the tx has been included in a block.
|
||||||
// - `'failed'` the tx failed for some reason, included on tx data.
|
// - `'failed'` the tx failed for some reason, included on tx data.
|
||||||
|
// - `'dropped'` the tx nonce was already used
|
||||||
_setTxStatus (txId, status) {
|
_setTxStatus (txId, status) {
|
||||||
const txMeta = this.getTx(txId)
|
const txMeta = this.getTx(txId)
|
||||||
txMeta.status = status
|
txMeta.status = status
|
@ -7,7 +7,7 @@ This migration updates "transaction state history" to diffs style
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const clone = require('clone')
|
const clone = require('clone')
|
||||||
const txStateHistoryHelper = require('../lib/tx-state-history-helper')
|
const txStateHistoryHelper = require('../controllers/transactions/lib/tx-state-history-helper')
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const NonceTracker = require('../../app/scripts/lib/nonce-tracker')
|
const NonceTracker = require('../../app/scripts/controllers/transactions/nonce-tracker')
|
||||||
const MockTxGen = require('../lib/mock-tx-gen')
|
const MockTxGen = require('../lib/mock-tx-gen')
|
||||||
let providerResultStub = {}
|
let providerResultStub = {}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ const EthTx = require('ethereumjs-tx')
|
|||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const clone = require('clone')
|
const clone = require('clone')
|
||||||
const { createTestProviderTools } = require('../stub/provider')
|
const { createTestProviderTools } = require('../stub/provider')
|
||||||
const PendingTransactionTracker = require('../../app/scripts/lib/pending-tx-tracker')
|
const PendingTransactionTracker = require('../../app/scripts/controllers/transactions/pending-tx-tracker')
|
||||||
const MockTxGen = require('../lib/mock-tx-gen')
|
const MockTxGen = require('../lib/mock-tx-gen')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const noop = () => true
|
const noop = () => true
|
||||||
|
@ -5,7 +5,7 @@ const EthjsQuery = require('ethjs-query')
|
|||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const TransactionController = require('../../app/scripts/controllers/transactions')
|
const TransactionController = require('../../app/scripts/controllers/transactions')
|
||||||
const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
|
const TxGasUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
|
||||||
const { createTestProviderTools } = require('../stub/provider')
|
const { createTestProviderTools } = require('../stub/provider')
|
||||||
|
|
||||||
const noop = () => true
|
const noop = () => true
|
||||||
@ -210,99 +210,6 @@ describe('Transaction Controller', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#_validateTxParams', function () {
|
|
||||||
it('does not throw for positive values', function () {
|
|
||||||
var sample = {
|
|
||||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
|
||||||
value: '0x01',
|
|
||||||
}
|
|
||||||
txController._validateTxParams(sample)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('returns error for negative values', function () {
|
|
||||||
var sample = {
|
|
||||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
|
||||||
value: '-0x01',
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
txController._validateTxParams(sample)
|
|
||||||
} catch (err) {
|
|
||||||
assert.ok(err, 'error')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#_normalizeTxParams', () => {
|
|
||||||
it('should normalize txParams', () => {
|
|
||||||
let txParams = {
|
|
||||||
chainId: '0x1',
|
|
||||||
from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
|
|
||||||
to: null,
|
|
||||||
data: '68656c6c6f20776f726c64',
|
|
||||||
random: 'hello world',
|
|
||||||
}
|
|
||||||
|
|
||||||
let normalizedTxParams = txController._normalizeTxParams(txParams)
|
|
||||||
|
|
||||||
assert(!normalizedTxParams.chainId, 'their should be no chainId')
|
|
||||||
assert(!normalizedTxParams.to, 'their should be no to address if null')
|
|
||||||
assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd')
|
|
||||||
assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd')
|
|
||||||
assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams')
|
|
||||||
|
|
||||||
txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
|
|
||||||
normalizedTxParams = txController._normalizeTxParams(txParams)
|
|
||||||
assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd')
|
|
||||||
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#_validateRecipient', () => {
|
|
||||||
it('removes recipient for txParams with 0x when contract data is provided', function () {
|
|
||||||
const zeroRecipientandDataTxParams = {
|
|
||||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
|
||||||
to: '0x',
|
|
||||||
data: 'bytecode',
|
|
||||||
}
|
|
||||||
const sanitizedTxParams = txController._validateRecipient(zeroRecipientandDataTxParams)
|
|
||||||
assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should error when recipient is 0x', function () {
|
|
||||||
const zeroRecipientTxParams = {
|
|
||||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
|
||||||
to: '0x',
|
|
||||||
}
|
|
||||||
assert.throws(() => { txController._validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
describe('#_validateFrom', () => {
|
|
||||||
it('should error when from is not a hex string', function () {
|
|
||||||
|
|
||||||
// where from is undefined
|
|
||||||
const txParams = {}
|
|
||||||
assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
|
||||||
|
|
||||||
// where from is array
|
|
||||||
txParams.from = []
|
|
||||||
assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
|
||||||
|
|
||||||
// where from is a object
|
|
||||||
txParams.from = {}
|
|
||||||
assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
|
||||||
|
|
||||||
// where from is a invalid address
|
|
||||||
txParams.from = 'im going to fail'
|
|
||||||
assert.throws(() => { txController._validateFrom(txParams) }, Error, `Invalid from address`)
|
|
||||||
|
|
||||||
// should run
|
|
||||||
txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
|
|
||||||
txController._validateFrom(txParams)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#addTx', function () {
|
describe('#addTx', function () {
|
||||||
it('should emit updates', function (done) {
|
it('should emit updates', function (done) {
|
||||||
const txMeta = {
|
const txMeta = {
|
||||||
|
@ -1,14 +1,77 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
|
const Transaction = require('ethereumjs-tx')
|
||||||
const { createTestProviderTools } = require('../stub/provider')
|
const BN = require('bn.js')
|
||||||
|
|
||||||
describe('Tx Gas Util', function () {
|
|
||||||
let txGasUtil, provider, providerResultStub
|
const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
|
||||||
beforeEach(function () {
|
const TxUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
|
||||||
providerResultStub = {}
|
|
||||||
provider = createTestProviderTools({ scaffold: providerResultStub }).provider
|
|
||||||
txGasUtil = new TxGasUtils({
|
describe('txUtils', function () {
|
||||||
provider,
|
let txUtils
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
txUtils = new TxUtils(new Proxy({}, {
|
||||||
|
get: (obj, name) => {
|
||||||
|
return () => {}
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('chain Id', function () {
|
||||||
|
it('prepares a transaction with the provided chainId', function () {
|
||||||
|
const txParams = {
|
||||||
|
to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
|
||||||
|
from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
|
||||||
|
value: '0x0',
|
||||||
|
gas: '0x7b0c',
|
||||||
|
gasPrice: '0x199c82cc00',
|
||||||
|
data: '0x',
|
||||||
|
nonce: '0x3',
|
||||||
|
chainId: 42,
|
||||||
|
}
|
||||||
|
const ethTx = new Transaction(txParams)
|
||||||
|
assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('addGasBuffer', function () {
|
||||||
|
it('multiplies by 1.5, when within block gas limit', function () {
|
||||||
|
// naive estimatedGas: 0x16e360 (1.5 mil)
|
||||||
|
const inputHex = '0x16e360'
|
||||||
|
// dummy gas limit: 0x3d4c52 (4 mil)
|
||||||
|
const blockGasLimitHex = '0x3d4c52'
|
||||||
|
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
||||||
|
const inputBn = hexToBn(inputHex)
|
||||||
|
const outputBn = hexToBn(output)
|
||||||
|
const expectedBn = inputBn.muln(1.5)
|
||||||
|
assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('uses original estimatedGas, when above block gas limit', function () {
|
||||||
|
// naive estimatedGas: 0x16e360 (1.5 mil)
|
||||||
|
const inputHex = '0x16e360'
|
||||||
|
// dummy gas limit: 0x0f4240 (1 mil)
|
||||||
|
const blockGasLimitHex = '0x0f4240'
|
||||||
|
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
||||||
|
// const inputBn = hexToBn(inputHex)
|
||||||
|
const outputBn = hexToBn(output)
|
||||||
|
const expectedBn = hexToBn(inputHex)
|
||||||
|
assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('buffers up to recommend gas limit recommended ceiling', function () {
|
||||||
|
// naive estimatedGas: 0x16e360 (1.5 mil)
|
||||||
|
const inputHex = '0x16e360'
|
||||||
|
// dummy gas limit: 0x1e8480 (2 mil)
|
||||||
|
const blockGasLimitHex = '0x1e8480'
|
||||||
|
const blockGasLimitBn = hexToBn(blockGasLimitHex)
|
||||||
|
const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
|
||||||
|
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
||||||
|
// const inputBn = hexToBn(inputHex)
|
||||||
|
// const outputBn = hexToBn(output)
|
||||||
|
const expectedHex = bnToHex(ceilGasLimitBn)
|
||||||
|
assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const clone = require('clone')
|
const clone = require('clone')
|
||||||
const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
|
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
|
||||||
|
|
||||||
describe('deepCloneFromTxMeta', function () {
|
describe('deepCloneFromTxMeta', function () {
|
||||||
it('should clone deep', function () {
|
it('should clone deep', function () {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
|
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
|
||||||
const testVault = require('../data/v17-long-history.json')
|
const testVault = require('../data/v17-long-history.json')
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const clone = require('clone')
|
const clone = require('clone')
|
||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const TxStateManager = require('../../app/scripts/lib/tx-state-manager')
|
const TxStateManager = require('../../app/scripts/controllers/transactions/tx-state-manager')
|
||||||
const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
|
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
|
||||||
const noop = () => true
|
const noop = () => true
|
||||||
|
|
||||||
describe('TransactionStateManager', function () {
|
describe('TransactionStateManager', function () {
|
||||||
|
@ -1,77 +1,98 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const Transaction = require('ethereumjs-tx')
|
const txUtils = require('../../app/scripts/controllers/transactions/lib/util')
|
||||||
const BN = require('bn.js')
|
|
||||||
|
|
||||||
|
|
||||||
const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
|
|
||||||
const TxUtils = require('../../app/scripts/lib/tx-gas-utils')
|
|
||||||
|
|
||||||
|
|
||||||
describe('txUtils', function () {
|
describe('txUtils', function () {
|
||||||
let txUtils
|
describe('#validateTxParams', function () {
|
||||||
|
it('does not throw for positive values', function () {
|
||||||
before(function () {
|
var sample = {
|
||||||
txUtils = new TxUtils(new Proxy({}, {
|
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||||
get: (obj, name) => {
|
value: '0x01',
|
||||||
return () => {}
|
}
|
||||||
},
|
txUtils.validateTxParams(sample)
|
||||||
}))
|
})
|
||||||
})
|
|
||||||
|
it('returns error for negative values', function () {
|
||||||
describe('chain Id', function () {
|
var sample = {
|
||||||
it('prepares a transaction with the provided chainId', function () {
|
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||||
const txParams = {
|
value: '-0x01',
|
||||||
to: '0x70ad465e0bab6504002ad58c744ed89c7da38524',
|
}
|
||||||
from: '0x69ad465e0bab6504002ad58c744ed89c7da38525',
|
try {
|
||||||
value: '0x0',
|
txUtils.validateTxParams(sample)
|
||||||
gas: '0x7b0c',
|
} catch (err) {
|
||||||
gasPrice: '0x199c82cc00',
|
assert.ok(err, 'error')
|
||||||
data: '0x',
|
|
||||||
nonce: '0x3',
|
|
||||||
chainId: 42,
|
|
||||||
}
|
}
|
||||||
const ethTx = new Transaction(txParams)
|
|
||||||
assert.equal(ethTx.getChainId(), 42, 'chainId is set from tx params')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('addGasBuffer', function () {
|
describe('#normalizeTxParams', () => {
|
||||||
it('multiplies by 1.5, when within block gas limit', function () {
|
it('should normalize txParams', () => {
|
||||||
// naive estimatedGas: 0x16e360 (1.5 mil)
|
let txParams = {
|
||||||
const inputHex = '0x16e360'
|
chainId: '0x1',
|
||||||
// dummy gas limit: 0x3d4c52 (4 mil)
|
from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
|
||||||
const blockGasLimitHex = '0x3d4c52'
|
to: null,
|
||||||
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
data: '68656c6c6f20776f726c64',
|
||||||
const inputBn = hexToBn(inputHex)
|
random: 'hello world',
|
||||||
const outputBn = hexToBn(output)
|
}
|
||||||
const expectedBn = inputBn.muln(1.5)
|
|
||||||
assert(outputBn.eq(expectedBn), 'returns 1.5 the input value')
|
let normalizedTxParams = txUtils.normalizeTxParams(txParams)
|
||||||
|
|
||||||
|
assert(!normalizedTxParams.chainId, 'their should be no chainId')
|
||||||
|
assert(!normalizedTxParams.to, 'their should be no to address if null')
|
||||||
|
assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd')
|
||||||
|
assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd')
|
||||||
|
assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams')
|
||||||
|
|
||||||
|
txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
|
||||||
|
normalizedTxParams = txUtils.normalizeTxParams(txParams)
|
||||||
|
assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd')
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#validateRecipient', () => {
|
||||||
|
it('removes recipient for txParams with 0x when contract data is provided', function () {
|
||||||
|
const zeroRecipientandDataTxParams = {
|
||||||
|
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||||
|
to: '0x',
|
||||||
|
data: 'bytecode',
|
||||||
|
}
|
||||||
|
const sanitizedTxParams = txUtils.validateRecipient(zeroRecipientandDataTxParams)
|
||||||
|
assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('uses original estimatedGas, when above block gas limit', function () {
|
it('should error when recipient is 0x', function () {
|
||||||
// naive estimatedGas: 0x16e360 (1.5 mil)
|
const zeroRecipientTxParams = {
|
||||||
const inputHex = '0x16e360'
|
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||||
// dummy gas limit: 0x0f4240 (1 mil)
|
to: '0x',
|
||||||
const blockGasLimitHex = '0x0f4240'
|
}
|
||||||
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
assert.throws(() => { txUtils.validateRecipient(zeroRecipientTxParams) }, Error, 'Invalid recipient address')
|
||||||
// const inputBn = hexToBn(inputHex)
|
|
||||||
const outputBn = hexToBn(output)
|
|
||||||
const expectedBn = hexToBn(inputHex)
|
|
||||||
assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
|
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('buffers up to recommend gas limit recommended ceiling', function () {
|
|
||||||
// naive estimatedGas: 0x16e360 (1.5 mil)
|
describe('#validateFrom', () => {
|
||||||
const inputHex = '0x16e360'
|
it('should error when from is not a hex string', function () {
|
||||||
// dummy gas limit: 0x1e8480 (2 mil)
|
|
||||||
const blockGasLimitHex = '0x1e8480'
|
// where from is undefined
|
||||||
const blockGasLimitBn = hexToBn(blockGasLimitHex)
|
const txParams = {}
|
||||||
const ceilGasLimitBn = blockGasLimitBn.muln(0.9)
|
assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
||||||
const output = txUtils.addGasBuffer(inputHex, blockGasLimitHex)
|
|
||||||
// const inputBn = hexToBn(inputHex)
|
// where from is array
|
||||||
// const outputBn = hexToBn(output)
|
txParams.from = []
|
||||||
const expectedHex = bnToHex(ceilGasLimitBn)
|
assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
||||||
assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
|
|
||||||
})
|
// where from is a object
|
||||||
|
txParams.from = {}
|
||||||
|
assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
||||||
|
|
||||||
|
// where from is a invalid address
|
||||||
|
txParams.from = 'im going to fail'
|
||||||
|
assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address`)
|
||||||
|
|
||||||
|
// should run
|
||||||
|
txParams.from ='0x1678a085c290ebd122dc42cba69373b5953b831d'
|
||||||
|
txUtils.validateFrom(txParams)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
Loading…
Reference in New Issue
Block a user