Skip to content

Commit

Permalink
update gas-price-oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
pertsev committed Jul 16, 2020
1 parent f8cb27e commit 1ac1b6c
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 103 deletions.
86 changes: 48 additions & 38 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,40 +1,50 @@
{
"env": {
"node": true,
"browser": true,
"es6": true,
"mocha": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
2,
{"SwitchCase": 1}
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
],
"object-curly-spacing": [
"error",
"always"
],
"require-await": "error"
}
"env": {
"node": true,
"browser": true,
"es6": true,
"mocha": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
2,
{
"SwitchCase": 1
}
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"never"
],
"object-curly-spacing": [
"error",
"always"
],
"require-await": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}
]
}
}
3 changes: 1 addition & 2 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require('dotenv').config()

module.exports = {
version: 2.7,
version: 2.8,
netId: Number(process.env.NET_ID) || 42,
redisUrl: process.env.REDIS_URL,
rpcUrl: process.env.RPC_URL || 'https://kovan.infura.io/',
Expand Down Expand Up @@ -145,7 +145,6 @@ module.exports = {
}
},
defaultGasPrice: 20,
gasOracleUrls: ['https://ethgasstation.info/json/ethgasAPI.json', 'https://gas-oracle.zoltu.io/'],
port: process.env.APP_PORT,
relayerServiceFee: Number(process.env.RELAYER_FEE),
maxGasPrice: process.env.MAX_GAS_PRICE || 200,
Expand Down
40 changes: 40 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "relay",
"version": "1.0.0",
"description": "Relayer for Tornado mixer. https://tornado.cash",
"description": "Relayer for Tornado.cash privacy solution. https://tornado.cash",
"main": "app.js",
"scripts": {
"start": "node app.js",
Expand All @@ -14,6 +14,7 @@
"bull": "^3.12.1",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"gas-price-oracle": "^0.1.4",
"ioredis": "^4.14.1",
"node-fetch": "^2.6.0",
"web3": "^1.2.2",
Expand Down
36 changes: 3 additions & 33 deletions src/Fetcher.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const fetch = require('node-fetch')
const Web3 = require('web3')
const { gasOracleUrls, defaultGasPrice, oracleRpcUrl, oracleAddress } = require('../config')
const { defaultGasPrice, oracleRpcUrl, oracleAddress } = require('../config')
const { getArgsForOracle } = require('./utils')
const { redisClient } = require('./redis')
const priceOracleABI = require('../abis/PriceOracle.abi.json')
Expand Down Expand Up @@ -39,46 +38,17 @@ class Fetcher {
return acc
}, {})
setTimeout(() => this.fetchPrices(), 1000 * 30)
} catch(e) {
} catch (e) {
console.error('fetchPrices', e.message)
setTimeout(() => this.fetchPrices(), 1000 * 30)
}
}
async fetchGasPrice({ oracleIndex = 0 } = {}) {
oracleIndex = (oracleIndex + 1) % gasOracleUrls.length
const url = gasOracleUrls[oracleIndex]
const delimiter = url === 'https://ethgasstation.info/json/ethgasAPI.json' ? 10 : 1
try {
const response = await fetch(url)
if (response.status === 200) {
const json = await response.json()
if (Number(json.fast) === 0) {
throw new Error('Fetch gasPrice failed')
}

if (json.fast) {
this.gasPrices.fast = Number(json.fast) / delimiter
}

if (json.percentile_97) {
this.gasPrices.fast = parseInt(json.percentile_90) + 1 / delimiter
}
// console.log('gas price fetch', this.gasPrices)
} else {
throw Error('Fetch gasPrice failed')
}
setTimeout(() => this.fetchGasPrice({ oracleIndex }), 15000)
} catch (e) {
console.log('fetchGasPrice', e.message)
setTimeout(() => this.fetchGasPrice({ oracleIndex }), 15000)
}
}
async fetchNonce() {
try {
const nonce = await this.web3.eth.getTransactionCount(this.web3.eth.defaultAccount)
await redisClient.set('nonce', nonce)
console.log(`Current nonce: ${nonce}`)
} catch(e) {
} catch (e) {
console.error('fetchNonce failed', e.message)
setTimeout(this.fetchNonce, 3000)
}
Expand Down
18 changes: 8 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {
maxGasPrice
} = require('../config')
const relayController = require('./relayController')
const { fetcher, web3 } = require('./instances')
const { fetcher, web3, gasPriceOracle } = require('./instances')
const { getMixers } = require('./utils')
const mixers = getMixers()
const { redisClient } = require('./redis')
Expand All @@ -26,7 +26,7 @@ app.use((err, req, res, next) => {
}
})

app.use(function(req, res, next) {
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
next()
Expand All @@ -39,11 +39,11 @@ app.get('/', function (req, res) {

app.get('/status', async function (req, res) {
let nonce = await redisClient.get('nonce')
const { ethPrices, gasPrices } = fetcher
const { ethPrices } = fetcher
res.json({
relayerAddress: web3.eth.defaultAccount,
mixers,
gasPrices,
gasPrices: await gasPriceOracle.gasPrices(),
netId,
ethPrices,
relayerServiceFee,
Expand All @@ -57,30 +57,28 @@ app.post('/relay', relayController)
let server = app.listen(port || 8000)
server.setTimeout(600000)
console.log('Gas price oracle started.')
fetcher.fetchGasPrice()
fetcher.fetchPrices()
fetcher.fetchNonce()

console.log('Relayer started on port', port || 8000)
console.log(`relayerAddress: ${web3.eth.defaultAccount}`)
console.log(`mixers: ${JSON.stringify(mixers)}`)
console.log(`gasPrices: ${JSON.stringify(fetcher.gasPrices)}`)
console.log(`netId: ${netId}`)
console.log(`ethPrices: ${JSON.stringify(fetcher.ethPrices)}`)

const { GAS_PRICE_BUMP_PERCENTAGE, ALLOWABLE_PENDING_TX_TIMEOUT, NONCE_WATCHER_INTERVAL, MAX_GAS_PRICE } = process.env
if(!NONCE_WATCHER_INTERVAL) {
if (!NONCE_WATCHER_INTERVAL) {
console.log(`NONCE_WATCHER_INTERVAL is not set. Using default value ${watherInterval / 1000} sec`)
}

if(!GAS_PRICE_BUMP_PERCENTAGE) {
if (!GAS_PRICE_BUMP_PERCENTAGE) {
console.log(`GAS_PRICE_BUMP_PERCENTAGE is not set. Using default value ${gasBumpPercentage}%`)
}

if(!ALLOWABLE_PENDING_TX_TIMEOUT) {
if (!ALLOWABLE_PENDING_TX_TIMEOUT) {
console.log(`ALLOWABLE_PENDING_TX_TIMEOUT is not set. Using default value ${pendingTxTimeout / 1000} sec`)
}

if(!MAX_GAS_PRICE) {
if (!MAX_GAS_PRICE) {
console.log(`ALLOWABLE_PENDING_TX_TIMEOUT is not set. Using default value ${maxGasPrice} Gwei`)
}
6 changes: 5 additions & 1 deletion src/instances.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
const { rpcUrl } = require('../config')
const Fetcher = require('./Fetcher')
const Sender = require('./sender')
const { GasPriceOracle } = require('gas-price-oracle')
const web3 = require('./setupWeb3')
const fetcher = new Fetcher(web3)
const sender = new Sender(web3)
const gasPriceOracle = new GasPriceOracle({ defaultRpc: rpcUrl })

module.exports = {
fetcher,
web3,
sender
sender,
gasPriceOracle
}
16 changes: 8 additions & 8 deletions src/relayController.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const {
const config = require('../config')
const { redisClient, redisOpts } = require('./redis')

const { web3, fetcher, sender } = require('./instances')
const { web3, fetcher, sender, gasPriceOracle } = require('./instances')
const withdrawQueue = new Queue('withdraw', redisOpts)

const reponseCbs = {}
Expand All @@ -22,26 +22,26 @@ async function relayController(req, resp) {
let requestJob

const { proof, args, contract } = req.body
let { valid , reason } = isValidProof(proof)
let { valid, reason } = isValidProof(proof)
if (!valid) {
console.log('Proof is invalid:', reason)
return resp.status(400).json({ error: 'Proof format is invalid' })
}

({ valid , reason } = isValidArgs(args))
({ valid, reason } = isValidArgs(args))
if (!valid) {
console.log('Args are invalid:', reason)
return resp.status(400).json({ error: 'Withdraw arguments are invalid' })
}

let currency, amount
( { valid, currency, amount } = isKnownContract(contract))
({ valid, currency, amount } = isKnownContract(contract))
if (!valid) {
console.log('Contract does not exist:', contract)
return resp.status(400).json({ error: 'This relayer does not support the token' })
}

const [ root, nullifierHash, recipient, relayer, fee, refund ] = [
const [root, nullifierHash, recipient, relayer, fee, refund] = [
args[0],
args[1],
toChecksumAddress(args[2]),
Expand All @@ -65,9 +65,9 @@ async function relayController(req, resp) {
reponseCbs[requestJob.id] = resp
}

withdrawQueue.process(async function(job, done){
withdrawQueue.process(async function (job, done) {
console.log(Date.now(), ' withdraw started', job.id)
const gasPrices = fetcher.gasPrices
const gasPrices = await gasPriceOracle.gasPrices()
const { contract, nullifierHash, root, proof, args, refund, currency, amount, fee } = job.data
console.log(JSON.stringify(job.data))
// job.data contains the custom data passed when the job was created
Expand Down Expand Up @@ -128,7 +128,7 @@ withdrawQueue.process(async function(job, done){
nonce
}
tx.date = Date.now()
await redisClient.set('tx:' + nonce, JSON.stringify(tx) )
await redisClient.set('tx:' + nonce, JSON.stringify(tx))
nonce += 1
await redisClient.set('nonce', nonce)
sender.sendTx(tx, done)
Expand Down
Loading

0 comments on commit 1ac1b6c

Please sign in to comment.