mirror of
https://github.com/tornadocash/tornado-relayer.git
synced 2024-10-01 08:25:37 -04:00
proper gas calculation
This commit is contained in:
parent
5352bd5a55
commit
db35a0cbcc
@ -3,3 +3,5 @@ RPC_URL=https://kovan.infura.io/v3/a3f4d001c1fc4a359ea70dd27fd9cb51
|
|||||||
PRIVATE_KEY=
|
PRIVATE_KEY=
|
||||||
ETH_MIXER_ADDRESS=0x1Cea940cA15a303A0E01B7F8589F39fF34308DB2
|
ETH_MIXER_ADDRESS=0x1Cea940cA15a303A0E01B7F8589F39fF34308DB2
|
||||||
DAI_MIXER_ADDRESS=0x7ed3fC8042e18db889A0466F49c438bB1410b3c7
|
DAI_MIXER_ADDRESS=0x7ed3fC8042e18db889A0466F49c438bB1410b3c7
|
||||||
|
|
||||||
|
APP_PORT=8000
|
@ -14,5 +14,6 @@ module.exports = {
|
|||||||
} ],
|
} ],
|
||||||
defaultGasPrice: 2,
|
defaultGasPrice: 2,
|
||||||
gasOracleUrls: ['https://www.etherchain.org/api/gasPriceOracle', 'https://gasprice.poa.network/'],
|
gasOracleUrls: ['https://www.etherchain.org/api/gasPriceOracle', 'https://gasprice.poa.network/'],
|
||||||
ethdaiAddress: '0x7Ef645705cb7D401C5CD91a395cfcc3Db3C93689'
|
ethdaiAddress: '0x7Ef645705cb7D401C5CD91a395cfcc3Db3C93689',
|
||||||
|
port: process.env.APP_PORT
|
||||||
}
|
}
|
47
index.js
47
index.js
@ -1,6 +1,6 @@
|
|||||||
const { numberToHex, toWei, toHex, toBN, toChecksumAddress } = require('web3-utils')
|
const { numberToHex, toWei, toHex, toBN, toChecksumAddress } = require('web3-utils')
|
||||||
const { netId, rpcUrl, privateKey, mixers, defaultGasPrice } = require('./config')
|
const { netId, rpcUrl, privateKey, mixers, defaultGasPrice, port } = require('./config')
|
||||||
const { fetchGasPrice, isValidProof, isValidArgs, fetchDAIprice, isKnownContract } = require('./utils')
|
const { fetchGasPrice, isValidProof, isValidArgs, fetchDAIprice, isKnownContract, isEnoughFee } = require('./utils')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
|
|
||||||
@ -70,32 +70,15 @@ app.post('/relay', async (req, resp) => {
|
|||||||
toBN(args[5])
|
toBN(args[5])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (currency === 'eth' && !refund.isZero()) {
|
||||||
|
return resp.status(400).json({ error: 'Cannot send refund for eth currency.' })
|
||||||
|
}
|
||||||
|
|
||||||
if (relayer !== web3.eth.defaultAccount) {
|
if (relayer !== web3.eth.defaultAccount) {
|
||||||
console.log('This proof is for different relayer:', relayer)
|
console.log('This proof is for different relayer:', relayer)
|
||||||
return resp.status(400).json({ error: 'Relayer address is invalid' })
|
return resp.status(400).json({ error: 'Relayer address is invalid' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN('1000000'))
|
|
||||||
let desiredFee
|
|
||||||
switch (currency) {
|
|
||||||
case 'eth': {
|
|
||||||
if (!refund.isZero()) {
|
|
||||||
return resp.status(400).json({ error: 'Cannot send refund for eth currency.' })
|
|
||||||
}
|
|
||||||
desiredFee = expense
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'dai': {
|
|
||||||
desiredFee = expense.add(refund).mul(toBN(ethPriceInDai)).div(toBN(10 ** 18))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fee.lt(desiredFee)) {
|
|
||||||
console.log('Fee is too low')
|
|
||||||
return resp.status(400).json({ error: 'Fee is too low. Try to resend.' })
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mixer = new web3.eth.Contract(mixerABI, req.body.contract)
|
const mixer = new web3.eth.Contract(mixerABI, req.body.contract)
|
||||||
const isSpent = await mixer.methods.isSpent(nullifierHash).call()
|
const isSpent = await mixer.methods.isSpent(nullifierHash).call()
|
||||||
@ -106,6 +89,7 @@ app.post('/relay', async (req, resp) => {
|
|||||||
if (!isKnownRoot) {
|
if (!isKnownRoot) {
|
||||||
return resp.status(400).json({ error: 'The merkle root is too old or invalid.' })
|
return resp.status(400).json({ error: 'The merkle root is too old or invalid.' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const withdrawArgs = [
|
const withdrawArgs = [
|
||||||
proof,
|
proof,
|
||||||
root,
|
root,
|
||||||
@ -115,14 +99,23 @@ app.post('/relay', async (req, resp) => {
|
|||||||
fee.toString(),
|
fee.toString(),
|
||||||
refund.toString()
|
refund.toString()
|
||||||
]
|
]
|
||||||
const gas = await mixer.methods.withdraw(...withdrawArgs).estimateGas({
|
let gas = await mixer.methods.withdraw(...withdrawArgs).estimateGas({
|
||||||
from: web3.eth.defaultAccount,
|
from: web3.eth.defaultAccount,
|
||||||
value: refund
|
value: refund
|
||||||
})
|
})
|
||||||
|
|
||||||
|
gas += 50000
|
||||||
|
|
||||||
|
const { isEnough, reason } = isEnoughFee({ gas, gasPrices, currency, refund, ethPriceInDai, fee })
|
||||||
|
if (!isEnough) {
|
||||||
|
console.log(`Wrong fee: ${reason}`)
|
||||||
|
return resp.status(400).json({ error: reason })
|
||||||
|
}
|
||||||
|
|
||||||
const result = mixer.methods.withdraw(...withdrawArgs).send({
|
const result = mixer.methods.withdraw(...withdrawArgs).send({
|
||||||
from: web3.eth.defaultAccount,
|
from: web3.eth.defaultAccount,
|
||||||
value: refund,
|
value: refund,
|
||||||
gas: numberToHex(gas + 50000),
|
gas: numberToHex(gas),
|
||||||
gasPrice: toHex(toWei(gasPrices.fast.toString(), 'gwei')),
|
gasPrice: toHex(toWei(gasPrices.fast.toString(), 'gwei')),
|
||||||
// TODO: nonce
|
// TODO: nonce
|
||||||
})
|
})
|
||||||
@ -139,7 +132,7 @@ app.post('/relay', async (req, resp) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
app.listen(8000)
|
app.listen(port || 8000)
|
||||||
|
|
||||||
if (Number(netId) === 1) {
|
if (Number(netId) === 1) {
|
||||||
fetchGasPrice({ gasPrices })
|
fetchGasPrice({ gasPrices })
|
||||||
@ -147,7 +140,7 @@ if (Number(netId) === 1) {
|
|||||||
console.log('Gas price oracle started.')
|
console.log('Gas price oracle started.')
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Relayer started')
|
console.log('Relayer started on port', port || 8000)
|
||||||
console.log(`relayerAddress: ${web3.eth.defaultAccount}`)
|
console.log(`relayerAddress: ${web3.eth.defaultAccount}`)
|
||||||
console.log(`mixers: ${JSON.stringify(mixers)}`)
|
console.log(`mixers: ${JSON.stringify(mixers)}`)
|
||||||
console.log(`gasPrices: ${JSON.stringify(gasPrices)}`)
|
console.log(`gasPrices: ${JSON.stringify(gasPrices)}`)
|
||||||
|
23
utils.js
23
utils.js
@ -1,5 +1,5 @@
|
|||||||
const fetch = require('node-fetch')
|
const fetch = require('node-fetch')
|
||||||
const { isHexStrict, hexToNumberString } = require('web3-utils')
|
const { isHexStrict, hexToNumberString, toBN, toWei } = require('web3-utils')
|
||||||
const { gasOracleUrls, ethdaiAddress, mixers } = require('./config')
|
const { gasOracleUrls, ethdaiAddress, mixers } = require('./config')
|
||||||
const oracleABI = require('./abis/ETHDAIOracle.json')
|
const oracleABI = require('./abis/ETHDAIOracle.json')
|
||||||
|
|
||||||
@ -97,4 +97,23 @@ function sleep(ms) {
|
|||||||
return new Promise(resolve => setTimeout(resolve, ms))
|
return new Promise(resolve => setTimeout(resolve, ms))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { fetchGasPrice, isValidProof, isValidArgs, sleep, fetchDAIprice, isKnownContract }
|
function isEnoughFee({ gas, gasPrices, currency, refund, ethPriceInDai, fee }) {
|
||||||
|
const expense = toBN(toWei(gasPrices.fast.toString(), 'gwei')).mul(toBN(gas))
|
||||||
|
let desiredFee
|
||||||
|
switch (currency) {
|
||||||
|
case 'eth': {
|
||||||
|
desiredFee = expense
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'dai': {
|
||||||
|
desiredFee = expense.add(refund).mul(toBN(ethPriceInDai)).div(toBN(10 ** 18))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fee.lt(desiredFee)) {
|
||||||
|
return { isEnough: false, reason: 'Not enough fee' }
|
||||||
|
}
|
||||||
|
return { isEnough: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { fetchGasPrice, isValidProof, isValidArgs, sleep, fetchDAIprice, isKnownContract, isEnoughFee }
|
||||||
|
Loading…
Reference in New Issue
Block a user