mirror of
https://github.com/tornadocash/tornado-relayer.git
synced 2025-05-09 18:14:57 -04:00
tree prover, rebuild tree and resubmit pending transactions
This commit is contained in:
parent
69a528795e
commit
90ed6cbe91
6 changed files with 286 additions and 8 deletions
241
abis/swap.abi.json
Normal file
241
abis/swap.abi.json
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "_torn",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_miningCap",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_initialLiquidity",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "constructor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "newWeight",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "PoolWeightUpdated",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "recipient",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "pTORN",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "TORN",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Swap",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "DURATION",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "initialLiquidity",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "liquidity",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "miner",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "poolWeight",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "startTimestamp",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "tokensSold",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "torn",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "contract IERC20",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "_miner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "init",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "recipient",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "swap",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getExpectedReturn",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "tornVirtualBalance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "newWeight",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setPoolWeight",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
|
@ -12,6 +12,7 @@ let config = {
|
||||||
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
||||||
oracleAddress: '0xA2b8E7ee7c8a18ea561A5CF7C9C365592026E374',
|
oracleAddress: '0xA2b8E7ee7c8a18ea561A5CF7C9C365592026E374',
|
||||||
minerAddress: '0x0834DeaFD83130AE1867173919f693070DaE6eeD',
|
minerAddress: '0x0834DeaFD83130AE1867173919f693070DaE6eeD',
|
||||||
|
swapAddress: '0x0834DeaFD83130AE1867173919f693070DaE6eeD',
|
||||||
minerMerkleTreeHeight: 10,
|
minerMerkleTreeHeight: 10,
|
||||||
privateKey: process.env.PRIVATE_KEY,
|
privateKey: process.env.PRIVATE_KEY,
|
||||||
instances: {
|
instances: {
|
||||||
|
|
|
@ -21,12 +21,14 @@
|
||||||
"gas-price-oracle": "^0.1.5",
|
"gas-price-oracle": "^0.1.5",
|
||||||
"ioredis": "^4.14.1",
|
"ioredis": "^4.14.1",
|
||||||
"node-fetch": "^2.6.0",
|
"node-fetch": "^2.6.0",
|
||||||
"tornado-cash-anonymity-mining": "git+https://github.com/tornadocash/tornado-anonymity-mining.git#820bd83254f3264cebaf255869641ebc33288dc3",
|
"tornado-cash-anonymity-mining": "git+https://github.com/tornadocash/tornado-anonymity-mining.git#e3ae8b98b14eb7fee7cb8c93221920a20b1e0cd8",
|
||||||
"uuid": "^8.3.0",
|
"uuid": "^8.3.0",
|
||||||
"web3": "^1.3.0",
|
"web3": "^1.3.0",
|
||||||
"web3-core-promievent": "^1.3.0",
|
"web3-core-promievent": "^1.3.0",
|
||||||
"web3-utils": "^1.2.2",
|
"web3-utils": "^1.2.2",
|
||||||
"why-is-node-running": "^2.2.0"
|
"why-is-node-running": "^2.2.0",
|
||||||
|
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
|
||||||
|
"websnark": "git+https://github.com/tornadocash/websnark.git#86a526718cd6f6f5d31bdb1fe26a9ec8819f633e"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
|
|
|
@ -28,6 +28,7 @@ async function getJob(uuid) {
|
||||||
|
|
||||||
async function getJobStatus(uuid) {
|
async function getJobStatus(uuid) {
|
||||||
const job = await getJob(uuid)
|
const job = await getJob(uuid)
|
||||||
|
// todo job.data doesn't contain current status and other stuff?
|
||||||
return job.data
|
return job.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
const fs = require('fs')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { numberToHex, toBN } = require('web3-utils')
|
const { numberToHex, toBN } = require('web3-utils')
|
||||||
const MerkleTree = require('fixed-merkle-tree')
|
const MerkleTree = require('fixed-merkle-tree')
|
||||||
|
@ -6,27 +7,46 @@ const { GasPriceOracle } = require('gas-price-oracle')
|
||||||
|
|
||||||
const tornadoABI = require('../abis/tornadoABI.json')
|
const tornadoABI = require('../abis/tornadoABI.json')
|
||||||
const miningABI = require('../abis/mining.abi.json')
|
const miningABI = require('../abis/mining.abi.json')
|
||||||
|
const swapABI = require('../abis/swap.abi.json')
|
||||||
const { queue } = require('./queue')
|
const { queue } = require('./queue')
|
||||||
const { poseidonHash2 } = require('./utils')
|
const { poseidonHash2 } = require('./utils')
|
||||||
const { rpcUrl, redisUrl, privateKey, updateConfig, rewardAccount, minerAddress } = require('../config')
|
const { rpcUrl, redisUrl, privateKey, updateConfig, swapAddress, rewardAccount, minerAddress } = require('../config')
|
||||||
const TxManager = require('./TxManager')
|
const TxManager = require('./TxManager')
|
||||||
|
const { Controller } = require('tornado-cash-anonymity-mining')
|
||||||
|
|
||||||
let web3
|
let web3
|
||||||
let currentTx
|
let currentTx
|
||||||
let currentJob
|
let currentJob
|
||||||
let tree
|
let tree
|
||||||
let txManager
|
let txManager
|
||||||
|
let controller
|
||||||
const redis = new Redis(redisUrl)
|
const redis = new Redis(redisUrl)
|
||||||
const redisSubscribe = new Redis(redisUrl)
|
const redisSubscribe = new Redis(redisUrl)
|
||||||
const gasPriceOracle = new GasPriceOracle({ defaultRpc: rpcUrl })
|
const gasPriceOracle = new GasPriceOracle({ defaultRpc: rpcUrl })
|
||||||
|
|
||||||
async function fetchTree() {
|
async function fetchTree() {
|
||||||
|
console.log('got tree update')
|
||||||
const elements = await redis.get('tree:elements')
|
const elements = await redis.get('tree:elements')
|
||||||
const convert = (_, val) => (typeof val === 'string' ? toBN(val) : val)
|
const convert = (_, val) => (typeof val === 'string' ? toBN(val) : val)
|
||||||
tree = MerkleTree.deserialize(JSON.parse(elements, convert), poseidonHash2)
|
tree = MerkleTree.deserialize(JSON.parse(elements, convert), poseidonHash2)
|
||||||
|
|
||||||
if (currentTx) {
|
if (currentTx && currentJob && ['miningReward', 'miningWithdraw'].includes(currentJob.data.type)) {
|
||||||
// todo replace
|
const { proof, args } = currentJob.data.data
|
||||||
|
if (args.account.inputRoot === tree.root()) { // todo check type
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = await controller.treeUpdate(args.account.outputCommitment, tree)
|
||||||
|
|
||||||
|
const instance = new web3.eth.Contract(tornadoABI, minerAddress)
|
||||||
|
const data = currentJob.data.type === 'miningReward' ?
|
||||||
|
instance.methods.reward(proof, args, update.proof, update.args).encodeABI() :
|
||||||
|
instance.methods.withdraw(proof, args, update.proof, update.args).encodeABI()
|
||||||
|
currentTx = await currentTx.replace({
|
||||||
|
to: minerAddress,
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
console.log('replaced pending tx')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,9 +54,15 @@ async function start() {
|
||||||
web3 = new Web3(rpcUrl)
|
web3 = new Web3(rpcUrl)
|
||||||
txManager = new TxManager({ privateKey, rpcUrl })
|
txManager = new TxManager({ privateKey, rpcUrl })
|
||||||
updateConfig({ rewardAccount: txManager.address })
|
updateConfig({ rewardAccount: txManager.address })
|
||||||
queue.process(process)
|
|
||||||
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
||||||
await fetchTree()
|
await fetchTree()
|
||||||
|
const provingKeys = {
|
||||||
|
treeUpdateCircuit: require('../keys/TreeUpdate.json'),
|
||||||
|
treeUpdateProvingKey: fs.readFileSync('./keys/TreeUpdate_proving_key.bin').buffer,
|
||||||
|
}
|
||||||
|
controller = new Controller({ provingKeys })
|
||||||
|
await controller.init()
|
||||||
|
queue.process(process)
|
||||||
console.log('Worker started')
|
console.log('Worker started')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +71,13 @@ async function checkTornadoFee(/* contract, fee, refund*/) {
|
||||||
console.log('fast', fast)
|
console.log('fast', fast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkMiningFee(points) {
|
||||||
|
const swap = new web3.eth.Contract(swapABI, swapAddress)
|
||||||
|
const TornAmount = await swap.getExpectedReturn(points).call()
|
||||||
|
|
||||||
|
// todo: use desired torn/eth rate and compute the same way as in tornado
|
||||||
|
}
|
||||||
|
|
||||||
async function process(job) {
|
async function process(job) {
|
||||||
switch (job.data.type) {
|
switch (job.data.type) {
|
||||||
case 'tornadoWithdraw':
|
case 'tornadoWithdraw':
|
||||||
|
|
|
@ -3862,9 +3862,9 @@ toidentifier@1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||||
|
|
||||||
"tornado-cash-anonymity-mining@git+https://github.com/tornadocash/tornado-anonymity-mining.git#820bd83254f3264cebaf255869641ebc33288dc3":
|
"tornado-cash-anonymity-mining@git+https://github.com/tornadocash/tornado-anonymity-mining.git#e3ae8b98b14eb7fee7cb8c93221920a20b1e0cd8":
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "git+https://github.com/tornadocash/tornado-anonymity-mining.git#820bd83254f3264cebaf255869641ebc33288dc3"
|
resolved "git+https://github.com/tornadocash/tornado-anonymity-mining.git#e3ae8b98b14eb7fee7cb8c93221920a20b1e0cd8"
|
||||||
dependencies:
|
dependencies:
|
||||||
circomlib "git+https://github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c"
|
circomlib "git+https://github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c"
|
||||||
eth-sig-util "^2.5.3"
|
eth-sig-util "^2.5.3"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue