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 Transaction = require('ethereumjs-tx')
|
||||
const EthQuery = require('ethjs-query')
|
||||
const TransactionStateManager = require('../lib/tx-state-manager')
|
||||
const TxGasUtil = require('../lib/tx-gas-utils')
|
||||
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
|
||||
const NonceTracker = require('../lib/nonce-tracker')
|
||||
|
||||
const TransactionStateManager = require('./tx-state-manager')
|
||||
const TxGasUtil = require('./tx-gas-utils')
|
||||
const PendingTransactionTracker = require('./pending-tx-tracker')
|
||||
const NonceTracker = require('./nonce-tracker')
|
||||
const txUtils = require('./lib/util')
|
||||
/*
|
||||
Transaction Controller is an aggregate of sub-controllers and trackers
|
||||
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) {
|
||||
// validate
|
||||
const normalizedTxParams = this._normalizeTxParams(txParams)
|
||||
this._validateTxParams(normalizedTxParams)
|
||||
const normalizedTxParams = txUtils.normalizeTxParams(txParams)
|
||||
txUtils.validateTxParams(normalizedTxParams)
|
||||
// construct txMeta
|
||||
let txMeta = this.txStateManager.generateTxMeta({ txParams: normalizedTxParams })
|
||||
this.addTx(txMeta)
|
||||
@ -314,60 +314,6 @@ module.exports = class TransactionController extends EventEmitter {
|
||||
// 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) {
|
||||
this.txStateManager.setTxStatusConfirmed(txId)
|
||||
// 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,
|
||||
BnMultiplyByFraction,
|
||||
bnToHex,
|
||||
} = require('./util')
|
||||
} = require('../../lib/util')
|
||||
const { addHexPrefix } = require('ethereumjs-util')
|
||||
const SIMPLE_GAS_COST = '0x5208' // Hex for 21000, cost of a simple send.
|
||||
|
@ -1,9 +1,9 @@
|
||||
const extend = require('xtend')
|
||||
const EventEmitter = require('events')
|
||||
const ObservableStore = require('obs-store')
|
||||
const createId = require('./random-id')
|
||||
const createId = require('../../lib/random-id')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const txStateHistoryHelper = require('./tx-state-history-helper')
|
||||
const txStateHistoryHelper = require('./lib/tx-state-history-helper')
|
||||
|
||||
// STATUS METHODS
|
||||
// statuses:
|
||||
@ -92,7 +92,9 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
||||
// or rejected tx's.
|
||||
// not tx's that are pending or unapproved
|
||||
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) {
|
||||
transactions.splice(index, 1)
|
||||
}
|
||||
@ -258,6 +260,16 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
||||
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) {
|
||||
// network only tx
|
||||
const txs = this.getFullTxList()
|
||||
@ -273,9 +285,8 @@ module.exports = class TransactionStateManager extends EventEmitter {
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
||||
// Should find the tx in the tx list and
|
||||
// update it.
|
||||
// should set the status in txData
|
||||
// STATUS METHODS
|
||||
// statuses:
|
||||
// - `'unapproved'` the user has not responded
|
||||
// - `'rejected'` the user has responded no!
|
||||
// - `'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
|
||||
// - `'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
|
||||
_setTxStatus (txId, status) {
|
||||
const txMeta = this.getTx(txId)
|
||||
txMeta.status = status
|
@ -7,7 +7,7 @@ This migration updates "transaction state history" to diffs style
|
||||
*/
|
||||
|
||||
const clone = require('clone')
|
||||
const txStateHistoryHelper = require('../lib/tx-state-history-helper')
|
||||
const txStateHistoryHelper = require('../controllers/transactions/lib/tx-state-history-helper')
|
||||
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,5 +1,5 @@
|
||||
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')
|
||||
let providerResultStub = {}
|
||||
|
||||
|
@ -4,7 +4,7 @@ const EthTx = require('ethereumjs-tx')
|
||||
const ObservableStore = require('obs-store')
|
||||
const clone = require('clone')
|
||||
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 sinon = require('sinon')
|
||||
const noop = () => true
|
||||
|
@ -5,7 +5,7 @@ const EthjsQuery = require('ethjs-query')
|
||||
const ObservableStore = require('obs-store')
|
||||
const sinon = require('sinon')
|
||||
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 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 () {
|
||||
it('should emit updates', function (done) {
|
||||
const txMeta = {
|
||||
|
@ -1,14 +1,77 @@
|
||||
const assert = require('assert')
|
||||
const TxGasUtils = require('../../app/scripts/lib/tx-gas-utils')
|
||||
const { createTestProviderTools } = require('../stub/provider')
|
||||
const Transaction = require('ethereumjs-tx')
|
||||
const BN = require('bn.js')
|
||||
|
||||
describe('Tx Gas Util', function () {
|
||||
let txGasUtil, provider, providerResultStub
|
||||
beforeEach(function () {
|
||||
providerResultStub = {}
|
||||
provider = createTestProviderTools({ scaffold: providerResultStub }).provider
|
||||
txGasUtil = new TxGasUtils({
|
||||
provider,
|
||||
|
||||
const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
|
||||
const TxUtils = require('../../app/scripts/controllers/transactions/tx-gas-utils')
|
||||
|
||||
|
||||
describe('txUtils', function () {
|
||||
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 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 () {
|
||||
it('should clone deep', function () {
|
||||
|
@ -1,5 +1,5 @@
|
||||
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')
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
const assert = require('assert')
|
||||
const clone = require('clone')
|
||||
const ObservableStore = require('obs-store')
|
||||
const TxStateManager = require('../../app/scripts/lib/tx-state-manager')
|
||||
const txStateHistoryHelper = require('../../app/scripts/lib/tx-state-history-helper')
|
||||
const TxStateManager = require('../../app/scripts/controllers/transactions/tx-state-manager')
|
||||
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
|
||||
const noop = () => true
|
||||
|
||||
describe('TransactionStateManager', function () {
|
||||
|
@ -1,77 +1,98 @@
|
||||
const assert = require('assert')
|
||||
const Transaction = require('ethereumjs-tx')
|
||||
const BN = require('bn.js')
|
||||
|
||||
|
||||
const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
|
||||
const TxUtils = require('../../app/scripts/lib/tx-gas-utils')
|
||||
const txUtils = require('../../app/scripts/controllers/transactions/lib/util')
|
||||
|
||||
|
||||
describe('txUtils', function () {
|
||||
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,
|
||||
describe('#validateTxParams', function () {
|
||||
it('does not throw for positive values', function () {
|
||||
var sample = {
|
||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||
value: '0x01',
|
||||
}
|
||||
txUtils.validateTxParams(sample)
|
||||
})
|
||||
|
||||
it('returns error for negative values', function () {
|
||||
var sample = {
|
||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||
value: '-0x01',
|
||||
}
|
||||
try {
|
||||
txUtils.validateTxParams(sample)
|
||||
} catch (err) {
|
||||
assert.ok(err, 'error')
|
||||
}
|
||||
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')
|
||||
describe('#normalizeTxParams', () => {
|
||||
it('should normalize txParams', () => {
|
||||
let txParams = {
|
||||
chainId: '0x1',
|
||||
from: 'a7df1beDBF813f57096dF77FCd515f0B3900e402',
|
||||
to: null,
|
||||
data: '68656c6c6f20776f726c64',
|
||||
random: 'hello world',
|
||||
}
|
||||
|
||||
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')
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
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')
|
||||
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('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')
|
||||
it('should error when recipient is 0x', function () {
|
||||
const zeroRecipientTxParams = {
|
||||
from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
|
||||
to: '0x',
|
||||
}
|
||||
assert.throws(() => { txUtils.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(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
||||
|
||||
// where from is array
|
||||
txParams.from = []
|
||||
assert.throws(() => { txUtils.validateFrom(txParams) }, Error, `Invalid from address ${txParams.from} not a string`)
|
||||
|
||||
// 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