mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Delete Balance controller and pending balances calculator (#8542)
This controller was not used. It was used by the `ComputedBalancesController`, which was removed in #7057 (as it was also unused). The pending balances calculator was only used by the balances controller.
This commit is contained in:
parent
a171bbe346
commit
7e75eb15ef
@ -1,134 +0,0 @@
|
||||
import ObservableStore from 'obs-store'
|
||||
import PendingBalanceCalculator from '../lib/pending-balance-calculator'
|
||||
import { BN } from 'ethereumjs-util'
|
||||
|
||||
export default class BalanceController {
|
||||
|
||||
/**
|
||||
* Controller responsible for storing and updating an account's balance.
|
||||
*
|
||||
* @typedef {Object} BalanceController
|
||||
* @param {Object} opts - Initialize various properties of the class.
|
||||
* @property {string} address A base 16 hex string. The account address which has the balance managed by this
|
||||
* BalanceController.
|
||||
* @property {AccountTracker} accountTracker Stores and updates the users accounts
|
||||
* for which this BalanceController manages balance.
|
||||
* @property {TransactionController} txController Stores, tracks and manages transactions. Here used to create a listener for
|
||||
* transaction updates.
|
||||
* @property {BlockTracker} blockTracker Tracks updates to blocks. On new blocks, this BalanceController updates its balance
|
||||
* @property {Object} store The store for the ethBalance
|
||||
* @property {string} store.ethBalance A base 16 hex string. The balance for the current account.
|
||||
* @property {PendingBalanceCalculator} balanceCalc Used to calculate the accounts balance with possible pending
|
||||
* transaction costs taken into account.
|
||||
*
|
||||
*/
|
||||
constructor (opts = {}) {
|
||||
this._validateParams(opts)
|
||||
const { address, accountTracker, txController, blockTracker } = opts
|
||||
|
||||
this.address = address
|
||||
this.accountTracker = accountTracker
|
||||
this.txController = txController
|
||||
this.blockTracker = blockTracker
|
||||
|
||||
const initState = {
|
||||
ethBalance: undefined,
|
||||
}
|
||||
this.store = new ObservableStore(initState)
|
||||
|
||||
this.balanceCalc = new PendingBalanceCalculator({
|
||||
getBalance: () => this._getBalance(),
|
||||
getPendingTransactions: this._getPendingTransactions.bind(this),
|
||||
})
|
||||
|
||||
this._registerUpdates()
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ethBalance property to the current pending balance
|
||||
*
|
||||
* @returns {Promise<void>} - Promises undefined
|
||||
*/
|
||||
async updateBalance () {
|
||||
const balance = await this.balanceCalc.getBalance()
|
||||
this.store.updateState({
|
||||
ethBalance: balance,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up listeners and subscriptions which should trigger an update of ethBalance. These updates include:
|
||||
* - when a transaction changes state to 'submitted', 'confirmed' or 'failed'
|
||||
* - when the current account changes (i.e. a new account is selected)
|
||||
* - when there is a block update
|
||||
*
|
||||
* @private
|
||||
*
|
||||
*/
|
||||
_registerUpdates () {
|
||||
const update = this.updateBalance.bind(this)
|
||||
|
||||
this.txController.on('tx:status-update', (_, status) => {
|
||||
switch (status) {
|
||||
case 'submitted':
|
||||
case 'confirmed':
|
||||
case 'failed':
|
||||
update()
|
||||
return
|
||||
default:
|
||||
return
|
||||
}
|
||||
})
|
||||
this.accountTracker.store.subscribe(update)
|
||||
this.blockTracker.on('latest', update)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the balance, as a base 16 hex string, of the account at this BalanceController's current address.
|
||||
* If the current account has no balance, returns undefined.
|
||||
*
|
||||
* @returns {Promise<BN|void>} - Promises a BN with a value equal to the balance of the current account, or undefined
|
||||
* if the current account has no balance
|
||||
*
|
||||
*/
|
||||
async _getBalance () {
|
||||
const { accounts } = this.accountTracker.store.getState()
|
||||
const entry = accounts[this.address]
|
||||
const balance = entry.balance
|
||||
return balance ? new BN(balance.substring(2), 16) : undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pending transactions (i.e. those with a 'submitted' status). These are accessed from the
|
||||
* TransactionController passed to this BalanceController during construction.
|
||||
*
|
||||
* @private
|
||||
* @returns {Promise<array>} - Promises an array of transaction objects.
|
||||
*
|
||||
*/
|
||||
async _getPendingTransactions () {
|
||||
const pending = this.txController.getFilteredTxList({
|
||||
from: this.address,
|
||||
status: 'submitted',
|
||||
err: undefined,
|
||||
})
|
||||
return pending
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that the passed options have all required properties.
|
||||
*
|
||||
* @param {Object} opts - The options object to validate
|
||||
* @throws {string} Throw a custom error indicating that address, accountTracker, txController and blockTracker are
|
||||
* missing and at least one is required
|
||||
*
|
||||
*/
|
||||
_validateParams (opts) {
|
||||
const { address, accountTracker, txController, blockTracker } = opts
|
||||
if (!address || !accountTracker || !txController || !blockTracker) {
|
||||
const error = 'Cannot construct a balance checker without address, accountTracker, txController, and blockTracker.'
|
||||
throw new Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
import { BN } from 'ethereumjs-util'
|
||||
import { normalize } from 'eth-sig-util'
|
||||
|
||||
export default class PendingBalanceCalculator {
|
||||
|
||||
/**
|
||||
* Used for calculating a users "pending balance": their current balance minus the total possible cost of all their
|
||||
* pending transactions.
|
||||
*
|
||||
* @typedef {Object} PendingBalanceCalculator
|
||||
* @param {Function} getBalance - Returns a promise of a BN of the current balance in Wei
|
||||
* @param {Function} 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the users "pending balance": their current balance minus the total possible cost of all their
|
||||
* pending transactions.
|
||||
*
|
||||
* @returns {Promise<string>} - Promises a base 16 hex string that contains the user's "pending balance"
|
||||
*
|
||||
*/
|
||||
async getBalance () {
|
||||
const results = await Promise.all([
|
||||
this.getNetworkBalance(),
|
||||
this.getPendingTransactions(),
|
||||
])
|
||||
|
||||
const [ balance, pending ] = results
|
||||
if (!balance) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const pendingValue = pending.reduce((total, tx) => {
|
||||
return total.add(this.calculateMaxCost(tx))
|
||||
}, new BN(0))
|
||||
|
||||
return `0x${balance.sub(pendingValue).toString(16)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum possible cost of a single transaction, based on the value, gas price and gas limit.
|
||||
*
|
||||
* @param {Object} tx - Contains all that data about a transaction.
|
||||
* @property {object} tx.txParams Contains data needed to calculate the maximum cost of the transaction: gas,
|
||||
* gasLimit and value.
|
||||
*
|
||||
* @returns {string} - Returns a base 16 hex string that contains the maximum possible cost of the transaction.
|
||||
*/
|
||||
calculateMaxCost (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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a hex string to a BN object
|
||||
*
|
||||
* @param {string} hex - A number represented as a hex string
|
||||
* @returns {Object} - A BN object
|
||||
*
|
||||
*/
|
||||
hexToBn (hex) {
|
||||
return new BN(normalize(hex).substring(2), 16)
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import { BN } from 'ethereumjs-util'
|
||||
|
||||
const template = {
|
||||
'status': 'submitted',
|
||||
'history': [{}],
|
||||
'txParams': {
|
||||
'from': '0x7d3517b0d011698406d6e0aed8453f0be2697926',
|
||||
'gas': '0x30d40',
|
||||
'value': '0x0',
|
||||
'nonce': '0x3',
|
||||
},
|
||||
}
|
||||
|
||||
class TxGenerator {
|
||||
|
||||
constructor () {
|
||||
this.txs = []
|
||||
}
|
||||
|
||||
generate (tx = {}, opts = {}) {
|
||||
const { count, fromNonce } = opts
|
||||
let nonce = fromNonce || this.txs.length
|
||||
const txs = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
txs.push(Object.assign({}, template, {
|
||||
txParams: {
|
||||
nonce: hexify(nonce++),
|
||||
},
|
||||
}, tx))
|
||||
}
|
||||
this.txs = this.txs.concat(txs)
|
||||
return txs
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function hexify (number) {
|
||||
return '0x' + (new BN(number)).toString(16)
|
||||
}
|
||||
|
||||
export default TxGenerator
|
@ -1,55 +0,0 @@
|
||||
import assert from 'assert'
|
||||
import ObservableStore from 'obs-store'
|
||||
import PollingBlockTracker from 'eth-block-tracker'
|
||||
import BalanceController from '../../../../app/scripts/controllers/balance'
|
||||
import AccountTracker from '../../../../app/scripts/lib/account-tracker'
|
||||
import TransactionController from '../../../../app/scripts/controllers/transactions'
|
||||
import { createTestProviderTools } from '../../../stub/provider'
|
||||
|
||||
const provider = createTestProviderTools({ scaffold: {} }).provider
|
||||
|
||||
const TEST_ADDRESS = '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'
|
||||
|
||||
const accounts = {
|
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
|
||||
balance: '0x5e942b06dc24c4d50',
|
||||
address: TEST_ADDRESS,
|
||||
},
|
||||
}
|
||||
|
||||
describe('Balance Controller', function () {
|
||||
|
||||
let balanceController
|
||||
|
||||
it('errors when address, accountTracker, txController, or blockTracker', function () {
|
||||
try {
|
||||
balanceController = new BalanceController()
|
||||
} catch (error) {
|
||||
assert.equal(error.message, 'Cannot construct a balance checker without address, accountTracker, txController, and blockTracker.')
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(function () {
|
||||
balanceController = new BalanceController({
|
||||
address: TEST_ADDRESS,
|
||||
accountTracker: new AccountTracker({
|
||||
provider,
|
||||
blockTracker: new PollingBlockTracker({ provider }),
|
||||
}),
|
||||
txController: new TransactionController({
|
||||
provider,
|
||||
networkStore: new ObservableStore(),
|
||||
blockTracker: new PollingBlockTracker({ provider }),
|
||||
}),
|
||||
blockTracker: new PollingBlockTracker({ provider }),
|
||||
})
|
||||
|
||||
balanceController.accountTracker.store.updateState({ accounts })
|
||||
})
|
||||
|
||||
it('updates balance controller ethBalance from account tracker', async function () {
|
||||
await balanceController.updateBalance()
|
||||
const balanceControllerState = balanceController.store.getState()
|
||||
assert.equal(balanceControllerState.ethBalance, '0x5e942b06dc24c4d50')
|
||||
})
|
||||
})
|
@ -1,85 +0,0 @@
|
||||
import assert from 'assert'
|
||||
import PendingBalanceCalculator from '../../../app/scripts/lib/pending-balance-calculator'
|
||||
import MockTxGen from '../../lib/mock-tx-gen'
|
||||
import { BN } from 'ethereumjs-util'
|
||||
|
||||
const zeroBn = new BN(0)
|
||||
const etherBn = new BN(String(1e18))
|
||||
const ether = '0x' + etherBn.toString(16)
|
||||
|
||||
describe('PendingBalanceCalculator', function () {
|
||||
let balanceCalculator, pendingTxs
|
||||
|
||||
describe('#calculateMaxCost(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.calculateMaxCost(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.calculateMaxCost(pendingTxs[0])
|
||||
assert.equal(result.toString(), '6', 'computes 6 wei of gas')
|
||||
})
|
||||
})
|
||||
|
||||
describe('if you have no pending txs and one ether', function () {
|
||||
it('returns the network balance', async function () {
|
||||
balanceCalculator = generateBalanceCalcWith([], etherBn)
|
||||
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 () {
|
||||
it('returns the subtracted result', async function () {
|
||||
const txGen = new MockTxGen()
|
||||
pendingTxs = txGen.generate({
|
||||
status: 'submitted',
|
||||
txParams: {
|
||||
value: ether,
|
||||
gasPrice: '0x0',
|
||||
gas: '0x0',
|
||||
},
|
||||
}, { count: 1 })
|
||||
|
||||
balanceCalculator = generateBalanceCalcWith(pendingTxs, etherBn)
|
||||
|
||||
const result = await balanceCalculator.getBalance()
|
||||
assert.equal(result, '0x0', `gave ${result} needed '0x0'`)
|
||||
return true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function generateBalanceCalcWith (transactions, providerStub = zeroBn) {
|
||||
const getPendingTransactions = async () => transactions
|
||||
const getBalance = async () => providerStub
|
||||
|
||||
return new PendingBalanceCalculator({
|
||||
getBalance,
|
||||
getPendingTransactions,
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user