Add v5 correct gas price/gas limit estimation
This commit is contained in:
parent
16a17079eb
commit
44f70bd41d
@ -13,12 +13,12 @@
|
|||||||
"prettier:fix": "npx prettier --write . --config .prettierrc",
|
"prettier:fix": "npx prettier --write . --config .prettierrc",
|
||||||
"lint": "yarn eslint && yarn prettier:check",
|
"lint": "yarn eslint && yarn prettier:check",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"start": "docker-compose up -d redis && concurrently \"yarn server\" \"yarn priceWatcher\" \"yarn treeWatcher \"yarn worker\" \"yarn healthWatcher\""
|
"start": "docker-compose up -d redis && concurrently \"yarn server\" \"yarn priceWatcher\" \"yarn treeWatcher\" \"yarn worker\" \"yarn healthWatcher\""
|
||||||
},
|
},
|
||||||
"author": "tornado.cash",
|
"author": "tornado.cash",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tornado/circomlib": "^0.0.20-p2",
|
"circomlib": "git+https://git.tornado.ws/tornado-packages/circomlib.git#3b492f9801573eebcfe1b6c584afe8a3beecf2b4",
|
||||||
"ajv": "^6.12.5",
|
"ajv": "^6.12.5",
|
||||||
"async-mutex": "^0.2.4",
|
"async-mutex": "^0.2.4",
|
||||||
"bull": "^3.12.1",
|
"bull": "^3.12.1",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
"eth-ens-namehash": "^2.0.8",
|
"eth-ens-namehash": "^2.0.8",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"fixed-merkle-tree": "^0.4.0",
|
"fixed-merkle-tree": "^0.4.0",
|
||||||
"gas-price-oracle": "^0.4.7",
|
"@tornado/gas-price-oracle": "^0.5.3",
|
||||||
"ioredis": "^4.14.1",
|
"ioredis": "^4.14.1",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"torn-token": "1.0.6",
|
"torn-token": "1.0.6",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const { instances, netId } = require('./config')
|
const { instances, netId } = require('./config')
|
||||||
const { poseidon } = require('@tornado/circomlib')
|
const { poseidon } = require('circomlib')
|
||||||
const { toBN, toChecksumAddress, BN, fromWei, isAddress, toWei } = require('web3-utils')
|
const { toBN, toChecksumAddress, BN, fromWei, isAddress, toWei, toHex } = require('web3-utils')
|
||||||
|
|
||||||
const TOKENS = {
|
const TOKENS = {
|
||||||
torn: {
|
torn: {
|
||||||
@ -161,6 +161,7 @@ module.exports = {
|
|||||||
toChecksumAddress,
|
toChecksumAddress,
|
||||||
fromWei,
|
fromWei,
|
||||||
toWei,
|
toWei,
|
||||||
|
toHex,
|
||||||
BN,
|
BN,
|
||||||
isAddress,
|
isAddress,
|
||||||
RelayerError,
|
RelayerError,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
const MerkleTree = require('fixed-merkle-tree')
|
||||||
const { GasPriceOracle } = require('gas-price-oracle')
|
const { GasPriceOracle } = require('@tornado/gas-price-oracle')
|
||||||
const { Utils, Controller } = require('tornado-anonymity-mining')
|
const { Utils, Controller } = require('tornado-anonymity-mining')
|
||||||
|
|
||||||
const swapABI = require('../abis/swap.abi.json')
|
const swapABI = require('../abis/swap.abi.json')
|
||||||
@ -15,6 +15,7 @@ const {
|
|||||||
sleep,
|
sleep,
|
||||||
toBN,
|
toBN,
|
||||||
toWei,
|
toWei,
|
||||||
|
toHex,
|
||||||
fromWei,
|
fromWei,
|
||||||
toChecksumAddress,
|
toChecksumAddress,
|
||||||
RelayerError,
|
RelayerError,
|
||||||
@ -46,7 +47,7 @@ let txManager
|
|||||||
let controller
|
let controller
|
||||||
let swap
|
let swap
|
||||||
let minerContract
|
let minerContract
|
||||||
const gasPriceOracle = new GasPriceOracle({ defaultRpc: oracleRpcUrl })
|
let gasPriceOracle
|
||||||
|
|
||||||
async function fetchTree() {
|
async function fetchTree() {
|
||||||
const elements = await redis.get('tree:elements')
|
const elements = await redis.get('tree:elements')
|
||||||
@ -93,6 +94,12 @@ async function start() {
|
|||||||
BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve,
|
BASE_FEE_RESERVE_PERCENTAGE: baseFeeReserve,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
gasPriceOracle = new GasPriceOracle({
|
||||||
|
defaultRpc: oracleRpcUrl,
|
||||||
|
minPriority: 2,
|
||||||
|
percentile: 5,
|
||||||
|
blocksCount: 20,
|
||||||
|
})
|
||||||
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address))
|
swap = new web3.eth.Contract(swapABI, await resolver.resolve(torn.rewardSwap.address))
|
||||||
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address))
|
minerContract = new web3.eth.Contract(miningABI, await resolver.resolve(torn.miningV2.address))
|
||||||
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
||||||
@ -111,31 +118,50 @@ async function start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFee({ data }) {
|
function checkFee({ data }, gasInfo) {
|
||||||
if (data.type === jobType.TORNADO_WITHDRAW) {
|
if (data.type === jobType.TORNADO_WITHDRAW) {
|
||||||
return checkTornadoFee(data)
|
return checkTornadoFee(data, gasInfo)
|
||||||
}
|
}
|
||||||
return checkMiningFee(data)
|
return checkMiningFee(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getGasPrice() {
|
async function getGasPrice() {
|
||||||
|
try {
|
||||||
|
const { maxFeePerGas, gasPrice } = await gasPriceOracle.getTxGasParams({
|
||||||
|
legacySpeed: 'fast',
|
||||||
|
bumpPercent: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
return toBN(maxFeePerGas || gasPrice)
|
||||||
|
} catch (e) {
|
||||||
const block = await web3.eth.getBlock('latest')
|
const block = await web3.eth.getBlock('latest')
|
||||||
|
|
||||||
if (block && block.baseFeePerGas) {
|
if (block && block.baseFeePerGas) {
|
||||||
return toBN(block.baseFeePerGas)
|
return toBN(block.baseFeePerGas)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { fast } = await gasPriceOracle.gasPrices()
|
const gasPrice = await web3.eth.getGasPrice()
|
||||||
return toBN(toWei(fast.toString(), 'gwei'))
|
return toBN(gasPrice)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkTornadoFee({ args, contract }) {
|
async function estimateWithdrawalGasLimit(tx) {
|
||||||
|
try {
|
||||||
|
const fetchedGasLimit = await web3.eth.estimateGas(tx)
|
||||||
|
const bumped = Math.floor(fetchedGasLimit * 1.2)
|
||||||
|
return bumped
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Estimation error: ', e)
|
||||||
|
return gasLimits[jobType.TORNADO_WITHDRAW]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkTornadoFee({ args, contract }, { gasLimit, gasPrice }) {
|
||||||
const { currency, amount, decimals } = getInstance(contract)
|
const { currency, amount, decimals } = getInstance(contract)
|
||||||
const [fee, refund] = [args[4], args[5]].map(toBN)
|
const [fee, refund] = [args[4], args[5]].map(toBN)
|
||||||
const gasPrice = await getGasPrice()
|
|
||||||
|
|
||||||
const ethPrice = await redis.hget('prices', currency)
|
const ethPrice = await redis.hget('prices', currency)
|
||||||
const expense = gasPrice.mul(toBN(gasLimits[jobType.TORNADO_WITHDRAW]))
|
const expense = toBN(gasPrice).mul(toBN(gasLimit))
|
||||||
|
|
||||||
const feePercent = toBN(fromDecimals(amount, decimals))
|
const feePercent = toBN(fromDecimals(amount, decimals))
|
||||||
.mul(toBN(parseInt(tornadoServiceFee * 1e10)))
|
.mul(toBN(parseInt(tornadoServiceFee * 1e10)))
|
||||||
@ -233,12 +259,17 @@ async function getTxObject({ data }) {
|
|||||||
calldata = contract.methods.withdraw(data.proof, ...data.args).encodeABI()
|
calldata = contract.methods.withdraw(data.proof, ...data.args).encodeABI()
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const gasPrice = await getGasPrice()
|
||||||
|
const incompleteTx = {
|
||||||
value: data.args[5],
|
value: data.args[5],
|
||||||
|
from: txManager.address, // Required, because without it relayerRegistry.burn will fail, because msg.sender is not relayer
|
||||||
to: contract._address,
|
to: contract._address,
|
||||||
data: calldata,
|
data: calldata,
|
||||||
gasLimit: gasLimits['WITHDRAW_WITH_EXTRA'],
|
gasPrice: toHex(gasPrice),
|
||||||
}
|
}
|
||||||
|
const gasLimit = await estimateWithdrawalGasLimit(incompleteTx)
|
||||||
|
|
||||||
|
return Object.assign(incompleteTx, { gasLimit })
|
||||||
} else {
|
} else {
|
||||||
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
||||||
const calldata = minerContract.methods[method](data.proof, data.args).encodeABI()
|
const calldata = minerContract.methods[method](data.proof, data.args).encodeABI()
|
||||||
@ -281,8 +312,9 @@ async function processJob(job) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function submitTx(job, retry = 0) {
|
async function submitTx(job, retry = 0) {
|
||||||
await checkFee(job)
|
const rawTx = await getTxObject(job)
|
||||||
currentTx = await txManager.createTx(await getTxObject(job))
|
await checkFee(job, rawTx)
|
||||||
|
currentTx = await txManager.createTx(rawTx)
|
||||||
|
|
||||||
if (job.data.type !== jobType.TORNADO_WITHDRAW) {
|
if (job.data.type !== jobType.TORNADO_WITHDRAW) {
|
||||||
await fetchTree()
|
await fetchTree()
|
||||||
|
Loading…
Reference in New Issue
Block a user