on master help sign in
Use BN consistently for gas calculations
commitfa53035b6169abbbae13dfbe3086dc867e922735 authorFang <git@fang.io> dateThu 22 Aug 2019, 16:42 (7 years ago) parenta9801ce
4 files changed+34−21
src/lib/reticket.js+3−3 src/lib/tank.js+22−14 src/lib/useEthereumTransaction.js+2−2 src/views/Invite/InviteEmail.js+7−2
src/lib/reticket.js+3−3
@@ -12,7 +12,7 @@ import { addHexPrefix } from './wallet';
1212import { sendAndAwaitAll } from './txn';
1313import getSuggestedGasPrice from './getSuggestedGasPrice';
1414import { GAS_LIMITS } from './constants';
15−import { toWei } from 'web3-utils';
15+import { toWei, toBN } from 'web3-utils';
1616
1717// the initial network key revision is always 1
1818const INITIAL_NETWORK_KEY_REVISION = 1;
@@ -144,13 +144,13 @@ export async function reticketPointBetweenWallets({
144144
145145 const suggestedGasPrice = await getSuggestedGasPrice(networkType);
146146 const gasPrice = parseInt(toWei(suggestedGasPrice.toFixed(), 'gwei'), 10);
147− let totalCost = 0;
147+ let totalCost = toBN(0);
148148 let inviteNonce = await web3.eth.getTransactionCount(fromWallet.address);
149149 txs = txs.map(tx => {
150150 tx.from = fromWallet.address;
151151 tx.nonce = inviteNonce++;
152152 tx.gasPrice = gasPrice;
153− totalCost = totalCost + tx.gasPrice * tx.gas;
153+ totalCost = totalCost.add(toBN(gasPrice).mul(toBN(tx.gas)));
154154 return tx;
155155 });
156156
src/lib/tank.js+22−14
@@ -1,6 +1,7 @@
11// /lib/tank: functions for funding transactions
22
33import retry from 'async-retry';
4+import { toBN } from 'web3-utils';
45import { RETRY_OPTIONS, waitForTransactionConfirm } from './txn';
56
67//NOTE if accessing this in a localhost configuration fails with "CORS request
@@ -53,9 +54,10 @@ const ensureFundsFor = async (
5354 askForFunding,
5455 gotFunding
5556) => {
56− let balance = await web3.eth.getBalance(address);
57+ let balance = toBN(await web3.eth.getBalance(address));
58+ cost = toBN(cost);
5759
58− if (web3.utils.toBN(cost).gt(web3.utils.toBN(balance))) {
60+ if (cost.gt(balance)) {
5961 try {
6062 if (point !== null) {
6163 const fundsRemaining = await remainingTransactions(point);
@@ -77,36 +79,42 @@ const ensureFundsFor = async (
7779 let newBalance = await web3.eth.getBalance(address);
7880 console.log(
7981 'tank: funds have confirmed',
80− balance >= cost,
81− balance,
82+ balance.toString(),
8283 newBalance
8384 );
8485 return true;
8586 }
8687 } catch (e) {
8788 console.log('tank: funding failed', e);
88− await waitForBalance(web3, address, cost, askForFunding, gotFunding);
89+ await waitForBalance(
90+ web3,
91+ address,
92+ cost.toString(),
93+ askForFunding,
94+ gotFunding
95+ );
8996 }
9097 } else {
91− console.log('tank: already have sufficient funds', cost, address, balance);
98+ console.log(
99+ 'tank: already have sufficient funds',
100+ cost.toString(),
101+ address,
102+ balance.toString()
103+ );
92104 }
93105 return false;
94106};
95107
96108// returns a promise that resolves when address has at least minBalance
97109function waitForBalance(web3, address, minBalance, askForFunding, gotFunding) {
110+ minBalance = toBN(minBalance);
98111 return retry(async (bail, n) => {
99− const balance = await web3.eth.getBalance(address);
100− if (web3.utils.toBN(balance).gte(web3.utils.toBN(minBalance))) {
112+ const balance = toBN(await web3.eth.getBalance(address));
113+ if (balance.gte(minBalance)) {
101114 gotFunding && gotFunding();
102115 return;
103116 } else {
104− // TODO: minBalance is a `number` type
105− // but we want to display ETH, which will never accept a number
106− // but instead wants string or BN/BigNumber.
107− // this will be heavily refactored to correctly do BN math, but until
108− // then we'll manually convert this number to an integer string
109− askForFunding(address, minBalance.toFixed(), balance);
117+ askForFunding(address, minBalance, balance);
110118 throw new Error('retrying');
111119 }
112120 }, RETRY_OPTIONS);
src/lib/useEthereumTransaction.js+2−2
@@ -1,6 +1,6 @@
11import { useCallback, useEffect, useState } from 'react';
22import { Just } from 'folktale/maybe';
3−import { toWei } from 'web3-utils';
3+import { toWei, toBN } from 'web3-utils';
44
55import { useNetwork } from 'store/network';
66import { useWallet } from 'store/wallet';
@@ -136,7 +136,7 @@ export default function useEthereumTransaction(
136136 setError(undefined);
137137
138138 const rawTx = hexify(signedTransaction.serialize());
139− const cost = toWei(gasPrice.toFixed(0), 'gwei') * gasLimit;
139+ const cost = toWei(toBN(gasLimit).mul(toBN(gasPrice)), 'gwei');
140140
141141 let usedTank = false;
142142 // if this ethereum transaction is being executed by a specific point
src/views/Invite/InviteEmail.js+7−2
@@ -18,7 +18,7 @@ import {
1818 AccessoryIcon,
1919} from 'indigo-react';
2020import { uniq } from 'lodash';
21−import { fromWei, toWei } from 'web3-utils';
21+import { fromWei, toWei, toBN } from 'web3-utils';
2222import { FieldArray } from 'react-final-form-arrays';
2323
2424import { usePointCursor } from 'store/pointCursor';
@@ -308,7 +308,12 @@ export default function InviteEmail() {
308308 _web3,
309309 point,
310310 _wallet.address,
311− toWei((gasPrice * GAS_LIMIT * emails.length).toFixed(), 'gwei'),
311+ toWei(
312+ toBN(GAS_LIMIT)
313+ .mul(toBN(gasPrice))
314+ .mul(toBN(emails.length)),
315+ 'gwei'
316+ ),
312317 names.map(name => invites[name].rawTx),
313318 (address, minBalance, balance) =>
314319 setNeedFunds({ address, minBalance, balance }),