tornado-relayer/src/worker.js

96 lines
2.9 KiB
JavaScript
Raw Normal View History

2020-09-28 05:28:34 +03:00
const Web3 = require('web3')
const { numberToHex, toBN } = require('web3-utils')
2020-09-28 05:28:34 +03:00
const MerkleTree = require('fixed-merkle-tree')
const Redis = require('ioredis')
const { GasPriceOracle } = require('gas-price-oracle')
const tornadoABI = require('../abis/tornadoABI.json')
const { queue } = require('./queue')
const { poseidonHash2 } = require('./utils')
const { rpcUrl, redisUrl, privateKey, updateConfig, rewardAccount } = require('../config')
const TxManager = require('./TxManager')
2020-09-28 05:28:34 +03:00
let web3
let currentTx
2020-09-29 06:17:42 +03:00
let currentJob
2020-09-28 05:28:34 +03:00
let tree
let txManager
const redis = new Redis(redisUrl)
const redisSubscribe = new Redis(redisUrl)
const gasPriceOracle = new GasPriceOracle({ defaultRpc: rpcUrl })
2020-09-28 05:28:34 +03:00
async function fetchTree() {
const elements = await redis.get('tree:elements')
const convert = (_, val) => (typeof val === 'string' ? toBN(val) : val)
2020-09-28 05:28:34 +03:00
tree = MerkleTree.deserialize(JSON.parse(elements, convert), poseidonHash2)
if (currentTx) {
// todo replace
}
}
async function start() {
2020-09-28 05:28:34 +03:00
web3 = new Web3(rpcUrl, null, { transactionConfirmationBlocks: 1 })
const account = web3.eth.accounts.privateKeyToAccount('0x' + privateKey)
web3.eth.accounts.wallet.add('0x' + privateKey)
web3.eth.defaultAccount = account.address
updateConfig({ rewardAccount: account.address })
txManager = new TxManager({ privateKey, rpcUrl })
queue.process(process)
redisSubscribe.subscribe('treeUpdate', fetchTree)
2020-09-28 05:28:34 +03:00
await fetchTree()
console.log('Worker started')
2020-09-28 05:28:34 +03:00
}
async function checkTornadoFee(/* contract, fee, refund*/) {
const { fast } = await gasPriceOracle.gasPrices()
console.log('fast', fast)
2020-09-28 05:28:34 +03:00
}
async function process(job) {
if (job.data.type !== 'tornadoWithdraw') {
2020-09-28 05:28:34 +03:00
throw new Error('not implemented')
}
2020-09-29 06:17:42 +03:00
currentJob = job
2020-09-28 05:28:34 +03:00
console.log(Date.now(), ' withdraw started', job.id)
const { proof, args, contract } = job.data.data
2020-09-28 05:28:34 +03:00
const fee = toBN(args[4])
const refund = toBN(args[5])
await checkTornadoFee(contract, fee, refund)
const instance = new web3.eth.Contract(tornadoABI, contract)
const data = instance.methods.withdraw(proof, ...args).encodeABI()
currentTx = await txManager.createTx({
2020-09-28 05:28:34 +03:00
value: numberToHex(refund),
to: contract,
data,
})
2020-09-28 05:28:34 +03:00
2020-09-29 06:17:42 +03:00
try {
await currentTx
.send()
.on('transactionHash', updateTxHash)
.on('mined', (receipt) => {
console.log('Mined in block', receipt.blockNumber)
})
.on('confirmations', updateConfirmations)
} catch (e) {
2020-09-29 06:17:42 +03:00
console.error('Revert', e)
throw new Error(`Revert by smart contract ${e.message}`)
}
}
async function updateTxHash(txHash) {
console.log(`A new successfully sent tx ${txHash}`)
currentJob.data.txHash = txHash
await currentJob.update(currentJob.data)
}
async function updateConfirmations(confirmations) {
console.log(`Confirmations count ${confirmations}`)
currentJob.data.confirmations = confirmations
await currentJob.update(currentJob.data)
2020-09-28 05:28:34 +03:00
}
module.exports = { start, process }