1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Merge branch 'i1746-BalanceBasedOnPending' into AddBalanceController

This commit is contained in:
Dan Finlay 2017-09-11 15:19:17 -07:00
commit 4738746968
2 changed files with 149 additions and 0 deletions

View File

@ -0,0 +1,51 @@
const BN = require('ethereumjs-util').BN
const normalize = require('eth-sig-util').normalize
class PendingBalanceCalculator {
// Must be initialized with two functions:
// getBalance => Returns a promise of a BN of the current balance in Wei
// getPendingTransactions => Returns an array of TxMeta Objects,
// which have txParams properties, which include value, gasPrice, and gas,
// all in a base=16 hex format.
constructor ({ getBalance, getPendingTransactions }) {
this.getPendingTransactions = getPendingTransactions
this.getNetworkBalance = getBalance
}
async getBalance() {
const results = await Promise.all([
this.getNetworkBalance(),
this.getPendingTransactions(),
])
const balance = results[0]
const pending = results[1]
const pendingValue = pending.reduce((total, tx) => {
return total.add(this.valueFor(tx))
}, new BN(0))
return `0x${balance.sub(pendingValue).toString(16)}`
}
valueFor (tx) {
const txValue = tx.txParams.value
const value = this.hexToBn(txValue)
const gasPrice = this.hexToBn(tx.txParams.gasPrice)
const gas = tx.txParams.gas
const gasLimit = tx.txParams.gasLimit
const gasLimitBn = this.hexToBn(gas || gasLimit)
const gasCost = gasPrice.mul(gasLimitBn)
return value.add(gasCost)
}
hexToBn (hex) {
return new BN(normalize(hex).substring(2), 16)
}
}
module.exports = PendingBalanceCalculator

View File

@ -0,0 +1,98 @@
const assert = require('assert')
const PendingBalanceCalculator = require('../../app/scripts/lib/pending-balance-calculator')
const MockTxGen = require('../lib/mock-tx-gen')
const BN = require('ethereumjs-util').BN
let providerResultStub = {}
const zeroBn = new BN(0)
const etherBn = new BN(String(1e18))
const ether = '0x' + etherBn.toString(16)
describe('PendingBalanceCalculator', function () {
let balanceCalculator
describe('#valueFor(tx)', function () {
it('returns a BN for a given tx value', function () {
const txGen = new MockTxGen()
pendingTxs = txGen.generate({
status: 'submitted',
txParams: {
value: ether,
gasPrice: '0x0',
gas: '0x0',
}
}, { count: 1 })
const balanceCalculator = generateBalanceCalcWith([], zeroBn)
const result = balanceCalculator.valueFor(pendingTxs[0])
assert.equal(result.toString(), etherBn.toString(), 'computes one ether')
})
it('calculates gas costs as well', function () {
const txGen = new MockTxGen()
pendingTxs = txGen.generate({
status: 'submitted',
txParams: {
value: '0x0',
gasPrice: '0x2',
gas: '0x3',
}
}, { count: 1 })
const balanceCalculator = generateBalanceCalcWith([], zeroBn)
const result = balanceCalculator.valueFor(pendingTxs[0])
assert.equal(result.toString(), '6', 'computes one ether')
})
})
describe('if you have no pending txs and one ether', function () {
beforeEach(function () {
balanceCalculator = generateBalanceCalcWith([], etherBn)
})
it('returns the network balance', async function () {
const result = await balanceCalculator.getBalance()
assert.equal(result, ether, `gave ${result} needed ${ether}`)
})
})
describe('if you have a one ether pending tx and one ether', function () {
beforeEach(function () {
const txGen = new MockTxGen()
pendingTxs = txGen.generate({
status: 'submitted',
txParams: {
value: ether,
gasPrice: '0x0',
gas: '0x0',
}
}, { count: 1 })
balanceCalculator = generateBalanceCalcWith(pendingTxs, etherBn)
})
it('returns the subtracted result', async function () {
const result = await balanceCalculator.getBalance()
assert.equal(result, '0x0', `gave ${result} needed '0x0'`)
return true
})
})
})
function generateBalanceCalcWith (transactions, providerStub = zeroBn) {
const getPendingTransactions = () => Promise.resolve(transactions)
const getBalance = () => Promise.resolve(providerStub)
providerResultStub.result = providerStub
const provider = {
sendAsync: (_, cb) => { cb(undefined, providerResultStub) },
_blockTracker: {
getCurrentBlock: () => '0x11b568',
},
}
return new PendingBalanceCalculator({
getBalance,
getPendingTransactions,
})
}