mirror of
https://github.com/tornadocash/tornado-relayer
synced 2024-02-02 15:04:06 +01:00
use ens
This commit is contained in:
parent
d22837d2bf
commit
cab8a2b8db
319
abis/Aggregator.abi.json
Normal file
319
abis/Aggregator.abi.json
Normal file
@ -0,0 +1,319 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32[]",
|
||||
"name": "domains",
|
||||
"type": "bytes32[]"
|
||||
}
|
||||
],
|
||||
"name": "bulkResolve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "result",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract Governance",
|
||||
"name": "governance",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getAllProposals",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "proposer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "startTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "endTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "forVotes",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "againstVotes",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "executed",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "extended",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "enum Governance.ProposalState",
|
||||
"name": "state",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"internalType": "struct GovernanceAggregator.Proposal[]",
|
||||
"name": "proposals",
|
||||
"type": "tuple[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract Governance",
|
||||
"name": "governance",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "accs",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "getGovernanceBalances",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "amounts",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "fromTokens",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "oneUnitAmounts",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "getPricesInETH",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "prices",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract Governance",
|
||||
"name": "governance",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getUserData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "latestProposalId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "latestProposalIdState",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "timelock",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "delegatee",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract Miner",
|
||||
"name": "miner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "instances",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "minerRates",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_rates",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "node",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "resolve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract RewardSwap",
|
||||
"name": "swap",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapState",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "poolWeight",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "contract Miner",
|
||||
"name": "miner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "instances",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "contract RewardSwap",
|
||||
"name": "swap",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "miningData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_rates",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "poolWeight",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "fromTokens",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "oneUnitAmounts",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "contract RewardSwap",
|
||||
"name": "swap",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "marketData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "prices",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
@ -13,7 +13,7 @@ services:
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
nginx_proxy_read_timeout: 600
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
treeWatcher:
|
||||
image: tornadocash/relayer
|
||||
@ -22,7 +22,7 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
priceWatcher:
|
||||
image: tornadocash/relayer
|
||||
@ -31,7 +31,7 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
worker1:
|
||||
image: tornadocash/relayer
|
||||
@ -40,16 +40,16 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
# worker2:
|
||||
# image: tornadocash/relayer
|
||||
# restart: always
|
||||
# command: worker
|
||||
# env_file: .env
|
||||
# environment:
|
||||
# PRIVATE_KEY: qwe
|
||||
# REDIS_URL: redis://redis/0
|
||||
# worker2:
|
||||
# image: tornadocash/relayer
|
||||
# restart: always
|
||||
# command: worker
|
||||
# env_file: .env
|
||||
# environment:
|
||||
# PRIVATE_KEY: qwe
|
||||
# REDIS_URL: redis://redis/0
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
|
@ -11,7 +11,7 @@ services:
|
||||
LETSENCRYPT_HOST: example.duckdns.org
|
||||
REDIS_URL: redis://redis/0
|
||||
nginx_proxy_read_timeout: 600
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
treeWatcher:
|
||||
image: tornadocash/relayer
|
||||
@ -20,7 +20,7 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
priceWatcher:
|
||||
image: tornadocash/relayer
|
||||
@ -29,7 +29,7 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
worker1:
|
||||
image: tornadocash/relayer
|
||||
@ -38,7 +38,7 @@ services:
|
||||
env_file: .env
|
||||
environment:
|
||||
REDIS_URL: redis://redis/0
|
||||
depends_on: [ redis ]
|
||||
depends_on: [redis]
|
||||
|
||||
# worker2:
|
||||
# image: tornadocash/relayer
|
||||
|
@ -21,14 +21,15 @@
|
||||
"bull": "^3.12.1",
|
||||
"circomlib": "git+ssh://git@github.com/tornadocash/circomlib.git#5beb6aee94923052faeecea40135d45b6ce6172c",
|
||||
"dotenv": "^8.2.0",
|
||||
"eth-ens-namehash": "^2.0.8",
|
||||
"express": "^4.17.1",
|
||||
"fixed-merkle-tree": "^0.4.0",
|
||||
"gas-price-oracle": "^0.2.2",
|
||||
"ioredis": "^4.14.1",
|
||||
"node-fetch": "^2.6.0",
|
||||
"torn-token": "git+ssh://git@github.com/tornadocash/torn-token.git#e119ff634fbe1b33b9643074bc2f6b08741c635f",
|
||||
"tornado-cash-anonymity-mining": "git+ssh://git@github.com/tornadocash/tornado-anonymity-mining.git#02ff4c9061eef94617b3c1b91a02c0d25bb1c410",
|
||||
"tx-manager": "git+ssh://git@github.com/tornadocash/tx-manager.git#df118be318b007e597e157504d105dfa3e6322a1",
|
||||
"torn-token": "git+ssh://git@github.com/tornadocash/torn-token.git#b90fc5adccbf9a87c3bdac6175a0e038a9ed3dd8",
|
||||
"uuid": "^8.3.0",
|
||||
"web3": "^1.3.0",
|
||||
"web3-core-promievent": "^1.3.0",
|
||||
|
@ -1,6 +1,7 @@
|
||||
require('dotenv').config()
|
||||
|
||||
const jobType = require('./jobTypes')
|
||||
const tornConfig = require('torn-token')
|
||||
|
||||
module.exports = {
|
||||
netId: Number(process.env.NET_ID) || 42,
|
||||
@ -9,12 +10,11 @@ module.exports = {
|
||||
wsRpcUrl: process.env.WS_RPC_URL,
|
||||
oracleRpcUrl: process.env.ORACLE_RPC_URL || 'https://mainnet.infura.io/',
|
||||
oracleAddress: '0xA2b8E7ee7c8a18ea561A5CF7C9C365592026E374',
|
||||
minerAddress: '0x3E0a9C6Cf76136862De28ce25a56cDBF38EF9D37', // each network has its own instance
|
||||
tornadoProxyAddress: '0x98529F6FaE5AdaFfa0AaDA37d9017AF9a4281E13', // each network has its own instance
|
||||
swapAddress: '0x1E73e0a484a595B692f3d212642AE4B3BF30E7e3',
|
||||
aggregatorAddress: '0x748F37B04eAB454Ad8cF4F5d6814984448c79B35',
|
||||
minerMerkleTreeHeight: 20,
|
||||
privateKey: process.env.PRIVATE_KEY,
|
||||
instances: require('torn-token').instances,
|
||||
instances: tornConfig.instances,
|
||||
torn: tornConfig,
|
||||
port: process.env.APP_PORT || 8000,
|
||||
tornadoServiceFee: Number(process.env.REGULAR_TORNADO_WITHDRAW_FEE),
|
||||
miningServiceFee: Number(process.env.MINING_SERVICE_FEE),
|
||||
|
30
src/resolver.js
Normal file
30
src/resolver.js
Normal file
@ -0,0 +1,30 @@
|
||||
const { httpRpcUrl, aggregatorAddress } = require('./config')
|
||||
const Web3 = require('web3')
|
||||
const web3 = new Web3(httpRpcUrl)
|
||||
const aggregator = new web3.eth.Contract(require('../abis/Aggregator.abi.json'), aggregatorAddress)
|
||||
const ens = require('eth-ens-namehash')
|
||||
|
||||
class ENSResolver {
|
||||
constructor() {
|
||||
this.addresses = {}
|
||||
}
|
||||
|
||||
async resolve(domains) {
|
||||
if (!Array.isArray(domains)) {
|
||||
domains = [domains]
|
||||
}
|
||||
|
||||
const unresolved = domains.filter(d => !this.addresses[d])
|
||||
if (unresolved.length) {
|
||||
const resolved = await aggregator.methods.bulkResolve(unresolved.map(ens.hash)).call()
|
||||
for (let i = 0; i < resolved.length; i++) {
|
||||
this.addresses[domains[i]] = resolved[i]
|
||||
}
|
||||
}
|
||||
|
||||
const addresses = domains.map(domain => this.addresses[domain])
|
||||
return addresses.length === 1 ? addresses[0] : addresses
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ENSResolver
|
@ -1,12 +1,15 @@
|
||||
const MerkleTree = require('fixed-merkle-tree')
|
||||
const { redisUrl, wsRpcUrl, minerMerkleTreeHeight, minerAddress } = require('./config')
|
||||
const { redisUrl, wsRpcUrl, minerMerkleTreeHeight, torn } = require('./config')
|
||||
const { poseidonHash2 } = require('./utils')
|
||||
const { toBN } = require('web3-utils')
|
||||
const Redis = require('ioredis')
|
||||
const redis = new Redis(redisUrl)
|
||||
const ENSResolver = require('./resolver')
|
||||
const resolver = new ENSResolver()
|
||||
const Web3 = require('web3')
|
||||
const web3 = new Web3(wsRpcUrl)
|
||||
const contract = new web3.eth.Contract(require('../abis/mining.abi.json'), minerAddress)
|
||||
const MinerABI = require('../abis/mining.abi.json')
|
||||
let contract
|
||||
|
||||
let tree, eventSubscription, blockSubscription
|
||||
|
||||
@ -86,6 +89,7 @@ async function rebuild() {
|
||||
|
||||
async function init() {
|
||||
console.log('Initializing')
|
||||
contract = new web3.eth.Contract(MinerABI, await resolver.resolve(torn.miningV2.address))
|
||||
const block = await web3.eth.getBlockNumber()
|
||||
const events = await fetchEvents(0, block)
|
||||
tree = new MerkleTree(minerMerkleTreeHeight, events, { hashFunction: poseidonHash2 })
|
||||
|
@ -14,17 +14,17 @@ const { poseidonHash2, getInstance, fromDecimals } = require('./utils')
|
||||
const jobType = require('./jobTypes')
|
||||
const {
|
||||
netId,
|
||||
torn,
|
||||
httpRpcUrl,
|
||||
redisUrl,
|
||||
privateKey,
|
||||
swapAddress,
|
||||
minerAddress,
|
||||
tornadoProxyAddress,
|
||||
gasLimits,
|
||||
instances,
|
||||
tornadoServiceFee,
|
||||
miningServiceFee,
|
||||
} = require('./config')
|
||||
const ENSResolver = require('./resolver')
|
||||
const resolver = new ENSResolver()
|
||||
const { TxManager } = require('tx-manager')
|
||||
const { Controller } = require('tornado-cash-anonymity-mining')
|
||||
|
||||
@ -63,6 +63,7 @@ async function fetchTree() {
|
||||
|
||||
const update = await controller.treeUpdate(args.account.outputCommitment, tree)
|
||||
|
||||
const minerAddress = await resolver.resolve(torn.miningV2.address)
|
||||
const instance = new web3.eth.Contract(miningABI, minerAddress)
|
||||
const data =
|
||||
currentJob.data.type === 'MINING_REWARD'
|
||||
@ -79,7 +80,7 @@ async function fetchTree() {
|
||||
async function start() {
|
||||
web3 = new Web3(httpRpcUrl)
|
||||
txManager = new TxManager({ privateKey, rpcUrl: httpRpcUrl, config: { CONFIRMATIONS: 6 } })
|
||||
swap = new web3.eth.Contract(swapABI, swapAddress)
|
||||
swap = new web3.eth.Contract(swapABI, resolver.resolve(torn.rewardSwap.address))
|
||||
redisSubscribe.subscribe('treeUpdate', fetchTree)
|
||||
await fetchTree()
|
||||
const provingKeys = {
|
||||
@ -168,16 +169,18 @@ async function checkMiningFee({ args }) {
|
||||
}
|
||||
}
|
||||
|
||||
function getTxObject({ data }) {
|
||||
async function getTxObject({ data }) {
|
||||
if (data.type === jobType.TORNADO_WITHDRAW) {
|
||||
const tornadoProxyAddress = await resolver.resolve(torn.tornadoProxy.address)
|
||||
const contract = new web3.eth.Contract(tornadoProxyABI, tornadoProxyAddress)
|
||||
const calldata = contract.methods.withdraw(data.contract, data.proof, ...data.args).encodeABI()
|
||||
return {
|
||||
value: data.args[5],
|
||||
to: tornadoProxyAddress,
|
||||
data: calldata
|
||||
data: calldata,
|
||||
}
|
||||
} else {
|
||||
const minerAddress = await resolver.resolve(torn.miningV2.address)
|
||||
const contract = new web3.eth.Contract(miningABI, minerAddress)
|
||||
const method = data.type === jobType.MINING_REWARD ? 'reward' : 'withdraw'
|
||||
const calldata = contract.methods[method](data.proof, data.args).encodeABI()
|
||||
@ -197,7 +200,7 @@ async function process(job) {
|
||||
await updateStatus(status.ACCEPTED)
|
||||
console.log(`Start processing a new ${job.data.type} job #${job.id}`)
|
||||
await checkFee(job)
|
||||
currentTx = await txManager.createTx(getTxObject(job))
|
||||
currentTx = await txManager.createTx(await getTxObject(job))
|
||||
|
||||
if (job.data.type !== jobType.TORNADO_WITHDRAW) {
|
||||
await fetchTree()
|
||||
|
@ -1466,7 +1466,7 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
eth-ens-namehash@2.0.8:
|
||||
eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8:
|
||||
version "2.0.8"
|
||||
resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf"
|
||||
integrity sha1-IprEbsqG1S4MmR58sq74P/D2i88=
|
||||
@ -3928,9 +3928,9 @@ toidentifier@1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
"torn-token@git+ssh://git@github.com/tornadocash/torn-token.git#b90fc5adccbf9a87c3bdac6175a0e038a9ed3dd8":
|
||||
"torn-token@git+ssh://git@github.com/tornadocash/torn-token.git#e119ff634fbe1b33b9643074bc2f6b08741c635f":
|
||||
version "1.0.0"
|
||||
resolved "git+ssh://git@github.com/tornadocash/torn-token.git#b90fc5adccbf9a87c3bdac6175a0e038a9ed3dd8"
|
||||
resolved "git+ssh://git@github.com/tornadocash/torn-token.git#e119ff634fbe1b33b9643074bc2f6b08741c635f"
|
||||
dependencies:
|
||||
"@openzeppelin/contracts" "^3.1.0"
|
||||
dotenv "^8.2.0"
|
||||
|
Loading…
Reference in New Issue
Block a user