on master help sign in
Merge pull request #523 from urbit/m/tip-the-tank

invite: send leftover eth back to the gas tank

commit17f04f3d6088c0c99fdcc0ac6560dac64d2b2fe1 authorfang <git@fang.io> dateTue 15 Sep 2020, 23:17 (6 years ago) parenta751ef009b3594
3 files changed+48−6
src/lib/reticket.js+37−2 src/lib/tank.js+8−1 src/lib/txn.js+3−3
src/lib/reticket.js+37−2
@@ -203,22 +203,57 @@ export async function reticketPointBetweenWallets({
203203
204204 progress(TRANSACTION_PROGRESS.TRANSFERRING);
205205
206− await sendAndAwaitAllSerial(
206+ const receipts = await sendAndAwaitAllSerial(
207207 web3,
208208 txPairs.map(p => p.signed),
209209 usedTank
210210 );
211211
212+ const realCost = gasPriceWeiBN.mul(
213+ receipts.reduce((sum, receipt) => {
214+ return sum.add(toBN(receipt.gasUsed));
215+ }, toBN(0))
216+ );
217+
212218 //
213219 // move leftover eth
214220 //
215221
216222 progress(TRANSACTION_PROGRESS.CLEANING);
217223
218− // if non-trivial eth left in invite wallet, transfer to new ownership
219224 let balance = toBN(await web3.eth.getBalance(fromWallet.address));
220225 const gasLimit = GAS_LIMITS.SEND_ETH;
221226 const sendEthCost = gasPriceWeiBN.mul(toBN(gasLimit));
227+
228+ // if we have funds left over from what the gas tank gave us, send those back
229+ if (usedTank && realCost.add(sendEthCost).lt(totalCost)) {
230+ try {
231+ const remainder = totalCost.sub(realCost).sub(sendEthCost);
232+ console.log('returning to gas tank', remainder.toString());
233+ const txn = { to: tank.TANK_ADDRESS, value: remainder };
234+ const stx = await signTransaction({
235+ wallet: fromWallet,
236+ walletType: fromWalletType,
237+ walletHdPath: fromWalletHdPath,
238+ txn,
239+ chainId,
240+ networkType,
241+ gasPrice: gasPriceGwei,
242+ gasLimit,
243+ nonce: inviteNonce,
244+ });
245+ sendSignedTransaction(web3, stx);
246+
247+ // only update these after the above succeeded
248+ inviteNonce++;
249+ balance = balance.sub(remainder).sub(sendEthCost);
250+ } catch (err) {
251+ console.log('error returning gas, safely ignored:');
252+ console.log(err);
253+ }
254+ }
255+
256+ // if non-trivial eth left in invite wallet, transfer to new ownership
222257 if (transferEth && balance.gt(sendEthCost)) {
223258 try {
224259 const value = balance.sub(sendEthCost);
src/lib/tank.js+8−1
@@ -5,6 +5,8 @@ import { toBN } from 'web3-utils';
55import { RETRY_OPTIONS, waitForTransactionConfirm } from './txn';
66import { WALLET_TYPES } from 'lib/wallet';
77
8+const TANK_ADDRESS = '0x40f0A6db85f8D7A54fF3eA915b040dE8Cd4A0Eb5';
9+
810//NOTE if accessing this in a localhost configuration fails with "CORS request
911// did not succeed", you might need to visit localhost:3001 or whatever
1012// explicitly and tell your browser that's safe to access.
@@ -142,4 +144,9 @@ function waitForBalance(web3, address, minBalance, askForFunding, gotFunding) {
142144 }, RETRY_OPTIONS);
143145}
144146
145−export { remainingTransactions, fundTransactions, ensureFundsFor };
147+export {
148+ TANK_ADDRESS,
149+ remainingTransactions,
150+ fundTransactions,
151+ ensureFundsFor,
152+};
src/lib/txn.js+3−3
@@ -164,7 +164,7 @@ const sendAndAwaitAll = (web3, stxs, doubtNonceError) => {
164164 return Promise.all(
165165 stxs.map(async tx => {
166166 const txHash = await sendSignedTransaction(web3, tx, doubtNonceError);
167− await waitForTransactionConfirm(web3, txHash);
167+ return await waitForTransactionConfirm(web3, txHash);
168168 })
169169 );
170170};
@@ -172,9 +172,9 @@ const sendAndAwaitAll = (web3, stxs, doubtNonceError) => {
172172const sendAndAwaitAllSerial = (web3, stxs, doubtNonceError) => {
173173 return stxs.reduce(
174174 (promise, stx) =>
175− promise.then(async () => {
175+ promise.then(async (receipts = []) => {
176176 const txHash = await sendSignedTransaction(web3, stx, doubtNonceError);
177− await waitForTransactionConfirm(web3, txHash);
177+ return [...receipts, await waitForTransactionConfirm(web3, txHash)];
178178 }),
179179 Promise.resolve()
180180 );