diff --git a/Dockerfile b/Dockerfile index 1702508..48d4ce6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,4 +10,5 @@ COPY package.json yarn.lock ./ RUN --mount=type=ssh yarn && yarn cache clean --force COPY . . +EXPOSE 8000 ENTRYPOINT ["yarn"] diff --git a/abis/tornadoProxyABI.json b/abis/tornadoProxyABI.json new file mode 100644 index 0000000..3c9f019 --- /dev/null +++ b/abis/tornadoProxyABI.json @@ -0,0 +1,171 @@ +[ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_tornadoTrees", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_governance", + "type": "bytes32" + }, + { + "internalType": "contract ITornado[]", + "name": "_instances", + "type": "address[]" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "governance", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITornado", + "name": "", + "type": "address" + } + ], + "name": "instances", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "node", + "type": "bytes32" + } + ], + "name": "resolve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tornadoTrees", + "outputs": [ + { + "internalType": "contract ITornadoTrees", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITornado", + "name": "tornado", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITornado", + "name": "instance", + "type": "address" + }, + { + "internalType": "bool", + "name": "update", + "type": "bool" + } + ], + "name": "updateInstances", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITornado", + "name": "tornado", + "type": "address" + }, + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "root", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "nullifierHash", + "type": "bytes32" + }, + { + "internalType": "address payable", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address payable", + "name": "relayer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "refund", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml deleted file mode 100644 index c9c9a1d..0000000 --- a/docker-compose.prod.yml +++ /dev/null @@ -1,98 +0,0 @@ -version: '2' - -services: - kovan: - image: tornadocash/relayer - restart: always - command: server - env_file: .env - expose: [8000] - environment: - VIRTUAL_HOST: example.duckdns.org - LETSENCRYPT_HOST: example.duckdns.org - REDIS_URL: redis://redis/0 - nginx_proxy_read_timeout: 600 - depends_on: - - redis - - treeWatcher: - image: tornadocash/relayer - restart: always - command: treeWatcher - env_file: .env - environment: - REDIS_URL: redis://redis/0 - - priceWatcher: - image: tornadocash/relayer - restart: always - command: priceWatcher - env_file: .env - environment: - REDIS_URL: redis://redis/0 - - worker1: - image: tornadocash/relayer - restart: always - command: worker - env_file: .env - environment: - 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 - restart: always - command: [redis-server, --appendonly, 'yes'] - volumes: - - redis:/data - - nginx: - image: nginx:alpine - container_name: nginx - restart: always - ports: - - 80:80 - - 443:443 - volumes: - - conf:/etc/nginx/conf.d - - vhost:/etc/nginx/vhost.d - - html:/usr/share/nginx/html - - certs:/etc/nginx/certs - logging: - driver: none - - dockergen: - image: poma/docker-gen - container_name: dockergen - restart: always - command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf - volumes_from: - - nginx - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - letsencrypt: - image: jrcs/letsencrypt-nginx-proxy-companion - container_name: letsencrypt - restart: always - environment: - NGINX_DOCKER_GEN_CONTAINER: dockergen - volumes_from: - - nginx - - dockergen - -volumes: - conf: - vhost: - html: - certs: - redis: diff --git a/docker-compose.test.yml b/docker-compose.test.yml new file mode 100644 index 0000000..90bf5dd --- /dev/null +++ b/docker-compose.test.yml @@ -0,0 +1,62 @@ +version: '2' + +# ssh-agent && ssh-add -K ~/.ssh/id_rsa +# DOCKER_BUILDKIT=1 docker build --ssh default -t tornadocash/relayer . +services: + server: + image: tornadocash/relayer + restart: always + command: server + env_file: .env + ports: + - 8000:8000 + environment: + REDIS_URL: redis://redis/0 + nginx_proxy_read_timeout: 600 + depends_on: [ redis ] + + treeWatcher: + image: tornadocash/relayer + restart: always + command: treeWatcher + env_file: .env + environment: + REDIS_URL: redis://redis/0 + depends_on: [ redis ] + + priceWatcher: + image: tornadocash/relayer + restart: always + command: priceWatcher + env_file: .env + environment: + REDIS_URL: redis://redis/0 + depends_on: [ redis ] + + worker1: + image: tornadocash/relayer + restart: always + command: worker + env_file: .env + environment: + REDIS_URL: redis://redis/0 + depends_on: [ redis ] + +# worker2: +# image: tornadocash/relayer +# restart: always +# command: worker +# env_file: .env +# environment: +# PRIVATE_KEY: qwe +# REDIS_URL: redis://redis/0 + + redis: + image: redis + restart: always + command: [redis-server, --appendonly, 'yes'] + volumes: + - redis:/data + +volumes: + redis: diff --git a/docker-compose.yml b/docker-compose.yml index 9b48b95..79dd8f4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,13 +6,12 @@ services: restart: always command: server env_file: .env - expose: [ 8000 ] - ports: [ 8000 ] environment: + VIRTUAL_HOST: example.duckdns.org + 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 @@ -21,6 +20,7 @@ services: env_file: .env environment: REDIS_URL: redis://redis/0 + depends_on: [ redis ] priceWatcher: image: tornadocash/relayer @@ -29,6 +29,7 @@ services: env_file: .env environment: REDIS_URL: redis://redis/0 + depends_on: [ redis ] worker1: image: tornadocash/relayer @@ -37,15 +38,16 @@ services: env_file: .env environment: REDIS_URL: redis://redis/0 + 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 @@ -54,6 +56,44 @@ services: volumes: - redis:/data -volumes: - redis: + nginx: + image: nginx:alpine + container_name: nginx + restart: always + ports: + - 80:80 + - 443:443 + volumes: + - conf:/etc/nginx/conf.d + - vhost:/etc/nginx/vhost.d + - html:/usr/share/nginx/html + - certs:/etc/nginx/certs + logging: + driver: none + dockergen: + image: poma/docker-gen + container_name: dockergen + restart: always + command: -notify-sighup nginx -watch /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf + volumes_from: + - nginx + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + + letsencrypt: + image: jrcs/letsencrypt-nginx-proxy-companion + container_name: letsencrypt + restart: always + environment: + NGINX_DOCKER_GEN_CONTAINER: dockergen + volumes_from: + - nginx + - dockergen + +volumes: + conf: + vhost: + html: + certs: + redis: diff --git a/src/config.js b/src/config.js index 34e9c35..648f6ea 100644 --- a/src/config.js +++ b/src/config.js @@ -10,6 +10,7 @@ module.exports = { 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', minerMerkleTreeHeight: 20, privateKey: process.env.PRIVATE_KEY, diff --git a/src/worker.js b/src/worker.js index 81c3c58..26922a5 100644 --- a/src/worker.js +++ b/src/worker.js @@ -6,7 +6,7 @@ const Redis = require('ioredis') const { GasPriceOracle } = require('gas-price-oracle') const { Utils } = require('tornado-cash-anonymity-mining') -const tornadoABI = require('../abis/tornadoABI.json') +const tornadoProxyABI = require('../abis/tornadoProxyABI.json') const miningABI = require('../abis/mining.abi.json') const swapABI = require('../abis/swap.abi.json') const { queue } = require('./queue') @@ -19,6 +19,7 @@ const { privateKey, swapAddress, minerAddress, + tornadoProxyAddress, gasLimits, instances, tornadoServiceFee, @@ -168,19 +169,22 @@ async function checkMiningFee({ args }) { } function getTxObject({ data }) { - let [ABI, contractAddress, value, args] = - data.type === jobType.TORNADO_WITHDRAW - ? [tornadoABI, data.contract, data.args[5], data.args] - : [miningABI, minerAddress, 0, [data.args]] - const method = data.type !== jobType.MINING_REWARD ? 'withdraw' : 'reward' - - const contract = new web3.eth.Contract(ABI, contractAddress) - const calldata = contract.methods[method](data.proof, ...args).encodeABI() - - return { - value, - to: contractAddress, - data: calldata, + if (data.type === jobType.TORNADO_WITHDRAW) { + 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 + } + } else { + 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() + return { + to: minerAddress, + data: calldata, + } } }