eth-to-bnc-bridge/src/oracle/bncWatcher/bncWatcher.js

120 lines
3.3 KiB
JavaScript
Raw Normal View History

2019-07-07 12:58:35 -07:00
const axios = require('axios')
const BN = require('bignumber.js')
const fs = require('fs')
const { computeAddress } = require('ethers').utils
2019-07-07 12:58:35 -07:00
2019-10-06 03:36:29 -07:00
const logger = require('./logger')
const redis = require('./db')
const { publicKeyToAddress } = require('./crypto')
2019-11-03 02:54:34 -08:00
const { delay, retry } = require('./wait')
2019-10-06 03:36:29 -07:00
const { FOREIGN_URL, PROXY_URL, FOREIGN_ASSET } = process.env
2019-07-07 12:58:35 -07:00
2019-11-01 11:43:25 -07:00
const FOREIGN_START_TIME = parseInt(process.env.FOREIGN_START_TIME, 10)
const FOREIGN_FETCH_INTERVAL = parseInt(process.env.FOREIGN_FETCH_INTERVAL, 10)
const FOREIGN_FETCH_BLOCK_TIME_OFFSET = parseInt(process.env.FOREIGN_FETCH_BLOCK_TIME_OFFSET, 10)
2019-10-31 12:43:34 -07:00
2019-07-07 12:58:35 -07:00
const foreignHttpClient = axios.create({ baseURL: FOREIGN_URL })
const proxyHttpClient = axios.create({ baseURL: PROXY_URL })
2019-11-01 11:43:25 -07:00
function getLastForeignAddress() {
const epoch = Math.max(0, ...fs.readdirSync('/keys')
.map((x) => parseInt(x.split('.')[0].substr(4), 10)))
if (epoch === 0) {
return null
2019-07-07 12:58:35 -07:00
}
2019-11-01 11:43:25 -07:00
const keysFile = `/keys/keys${epoch}.store`
const publicKey = JSON.parse(fs.readFileSync(keysFile))[5]
return publicKeyToAddress(publicKey)
2019-07-07 12:58:35 -07:00
}
2019-11-03 02:54:34 -08:00
async function getTx(hash) {
const response = await retry(() => foreignHttpClient.get(
`/api/v1/tx/${hash}`,
{
params: {
format: 'json'
}
2019-11-03 02:54:34 -08:00
}
))
return response.data.tx.value
}
2019-11-03 02:54:34 -08:00
async function getBlockTime() {
const response = await retry(() => foreignHttpClient.get('/api/v1/time'))
return Date.parse(response.data.block_time) - FOREIGN_FETCH_BLOCK_TIME_OFFSET
}
2019-11-01 11:43:25 -07:00
async function fetchNewTransactions() {
2019-10-06 03:36:29 -07:00
logger.debug('Fetching new transactions')
2019-11-01 11:43:25 -07:00
const startTime = parseInt(await redis.get('foreignTime'), 10) + 1
2019-10-07 06:49:20 -07:00
const address = getLastForeignAddress()
2019-10-31 12:43:34 -07:00
const endTime = Math.min(startTime + 3 * 30 * 24 * 60 * 60 * 1000, await getBlockTime())
2019-11-01 11:43:25 -07:00
if (address === null) {
return {}
2019-11-01 11:43:25 -07:00
}
2019-10-06 03:36:29 -07:00
logger.debug('Sending api transactions request')
const params = {
address,
side: 'RECEIVE',
txAsset: FOREIGN_ASSET,
txType: 'TRANSFER',
startTime,
2019-11-01 11:43:25 -07:00
endTime
}
2019-11-03 02:54:34 -08:00
logger.trace('%o', params)
const transactions = (await retry(() => foreignHttpClient
.get('/api/v1/transactions', { params }))).data.tx
return {
transactions,
endTime
}
2019-07-07 12:58:35 -07:00
}
2019-11-01 11:43:25 -07:00
async function initialize() {
if (await redis.get('foreignTime') === null) {
logger.info('Set default foreign time')
await redis.set('foreignTime', FOREIGN_START_TIME)
}
2019-07-07 12:58:35 -07:00
}
2019-11-03 02:54:34 -08:00
async function loop() {
2019-11-01 11:43:25 -07:00
const { transactions, endTime } = await fetchNewTransactions()
if (!transactions || transactions.length === 0) {
logger.debug('Found 0 new transactions')
2019-11-03 02:54:34 -08:00
await delay(FOREIGN_FETCH_INTERVAL)
2019-11-01 11:43:25 -07:00
return
}
logger.info(`Found ${transactions.length} new transactions`)
logger.trace('%o', transactions)
for (let i = transactions.length - 1; i >= 0; i -= 1) {
const tx = transactions[i]
if (tx.memo !== 'funding') {
const publicKeyEncoded = (await getTx(tx.txHash)).signatures[0].pub_key.value
await proxyHttpClient
.post('/transfer', {
to: computeAddress(Buffer.from(publicKeyEncoded, 'base64')),
2019-11-03 02:54:34 -08:00
value: new BN(tx.value)
.multipliedBy(10 ** 18)
2019-11-01 11:43:25 -07:00
.integerValue(),
hash: `0x${tx.txHash}`
})
}
2019-07-07 12:58:35 -07:00
}
2019-11-01 11:43:25 -07:00
await redis.set('foreignTime', endTime)
}
2019-11-03 02:54:34 -08:00
async function main() {
await initialize()
while (true) {
await loop()
}
}
main()