diff --git a/src/oracle/bncWatcher/bncWatcher.js b/src/oracle/bncWatcher/bncWatcher.js index f9ef526..e103a10 100644 --- a/src/oracle/bncWatcher/bncWatcher.js +++ b/src/oracle/bncWatcher/bncWatcher.js @@ -6,6 +6,8 @@ const fs = require('fs') const crypto = require('crypto') const { computeAddress } = require('ethers').utils +const logger = require('./logger') + const { FOREIGN_URL, PROXY_URL, FOREIGN_ASSET } = process.env const foreignHttpClient = axios.create({ baseURL: FOREIGN_URL }) @@ -13,7 +15,7 @@ const proxyHttpClient = axios.create({ baseURL: PROXY_URL }) async function initialize () { if (await redis.get('foreignTime') === null) { - console.log('Set default foreign time') + logger.info('Set default foreign time') await redis.set('foreignTime', 1562306990672) } } @@ -26,7 +28,10 @@ async function main () { return } - console.log(`Found ${newTransactions.length} new transactions`) + if (newTransactions.length) + logger.info(`Found ${newTransactions.length} new transactions`) + else + logger.debug(`Found 0 new transactions`) for (const tx of newTransactions.reverse()) { if (tx.memo !== 'funding') { @@ -54,12 +59,12 @@ function getTx(hash) { } async function fetchNewTransactions () { - console.log('Fetching new transactions') + logger.debug('Fetching new transactions') const startTime = parseInt(await redis.get('foreignTime')) + 1 const address = await getLastForeignAddress() if (address === null) return null - console.log('Sending api transactions request') + logger.debug('Sending api transactions request') return foreignHttpClient .get('/api/v1/transactions', { params: { diff --git a/src/oracle/docker-compose-test.yml b/src/oracle/docker-compose-test.yml index 9cca490..fea51cb 100644 --- a/src/oracle/docker-compose-test.yml +++ b/src/oracle/docker-compose-test.yml @@ -16,6 +16,7 @@ services: - VALIDATOR_PRIVATE_KEY - FOREIGN_URL - FOREIGN_ASSET + - 'LOG_LEVEL=info' volumes: - '../deploy/deploy-test/build/contracts/IERC20.json:/proxy/contracts_data/IERC20.json' - '../deploy/deploy-home/build/contracts/Bridge.json:/proxy/contracts_data/Bridge.json' @@ -34,6 +35,7 @@ services: environment: - 'RABBITMQ_URL=amqp://rabbitmq:5672' - 'PROXY_URL=http://proxy:8001' + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' networks: @@ -49,6 +51,7 @@ services: - FOREIGN_CHAIN_ID - FOREIGN_URL - FOREIGN_ASSET + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' ports: @@ -82,6 +85,7 @@ services: - HOME_CHAIN_ID - HOME_START_BLOCK - 'RABBITMQ_URL=amqp://rabbitmq:5672' + - 'LOG_LEVEL=info' volumes: - '../deploy/deploy-home/build/contracts/Bridge.json:/watcher/contracts_data/Bridge.json' - '../deploy/deploy-test/build/contracts/IERC20.json:/watcher/contracts_data/IERC20.json' @@ -98,6 +102,7 @@ services: - FOREIGN_ASSET - 'RABBITMQ_URL=amqp://rabbitmq:5672' - 'PROXY_URL=http://proxy:8001' + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' networks: diff --git a/src/oracle/docker-compose.yml b/src/oracle/docker-compose.yml index 77a9dc5..c5030c9 100644 --- a/src/oracle/docker-compose.yml +++ b/src/oracle/docker-compose.yml @@ -16,6 +16,7 @@ services: - VALIDATOR_PRIVATE_KEY - FOREIGN_URL - FOREIGN_ASSET + - 'LOG_LEVEL=info' volumes: - '../deploy/deploy-test/build/contracts/IERC20.json:/proxy/contracts_data/IERC20.json' - '../deploy/deploy-home/build/contracts/Bridge.json:/proxy/contracts_data/Bridge.json' @@ -34,6 +35,7 @@ services: environment: - 'RABBITMQ_URL=amqp://rabbitmq:5672' - 'PROXY_URL=http://proxy:8001' + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' networks: @@ -51,6 +53,7 @@ services: - FOREIGN_CHAIN_ID - FOREIGN_URL - FOREIGN_ASSET + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' ports: @@ -92,6 +95,7 @@ services: - HOME_CHAIN_ID - HOME_START_BLOCK - 'RABBITMQ_URL=amqp://rabbitmq:5672' + - 'LOG_LEVEL=info' volumes: - '../deploy/deploy-home/build/contracts/Bridge.json:/watcher/contracts_data/Bridge.json' - '../deploy/deploy-test/build/contracts/IERC20.json:/watcher/contracts_data/IERC20.json' @@ -108,6 +112,7 @@ services: - FOREIGN_ASSET - 'RABBITMQ_URL=amqp://rabbitmq:5672' - 'PROXY_URL=http://proxy:8001' + - 'LOG_LEVEL=info' volumes: - '${PWD}/${TARGET_NETWORK}/keys:/keys' networks: diff --git a/src/oracle/ethWatcher/ethWatcher.js b/src/oracle/ethWatcher/ethWatcher.js index 1fa1783..5306096 100644 --- a/src/oracle/ethWatcher/ethWatcher.js +++ b/src/oracle/ethWatcher/ethWatcher.js @@ -8,8 +8,9 @@ const bech32 = require('bech32') const abiBridge = require('./contracts_data/Bridge.json').abi const abiToken = require('./contracts_data/IERC20.json').abi +const logger = require('./logger') -const { HOME_RPC_URL, HOME_CHAIN_ID, HOME_BRIDGE_ADDRESS, RABBITMQ_URL, HOME_TOKEN_ADDRESS, HOME_START_BLOCK } = process.env +const { HOME_RPC_URL, HOME_BRIDGE_ADDRESS, RABBITMQ_URL, HOME_TOKEN_ADDRESS, HOME_START_BLOCK } = process.env const web3Home = new Web3(HOME_RPC_URL) const bridge = new web3Home.eth.Contract(abiBridge, HOME_BRIDGE_ADDRESS) @@ -26,7 +27,7 @@ let redisTx async function connectRabbit (url) { return amqp.connect(url).catch(() => { - console.log('Failed to connect, reconnecting') + logger.debug('Failed to connect, reconnecting') return new Promise(resolve => setTimeout(() => resolve(connectRabbit(url)), 1000) ) @@ -44,12 +45,12 @@ async function initialize () { fromBlock: 1 }) epoch = events.length ? events[events.length - 1].returnValues.epoch.toNumber() : 0 - console.log(`Current epoch ${epoch}`) + logger.info(`Current epoch ${epoch}`) const epochStart = events.length ? events[events.length - 1].blockNumber : 1 const saved = (parseInt(await redis.get('homeBlock')) + 1) || parseInt(HOME_START_BLOCK) - console.log(epochStart, saved) + logger.debug(epochStart, saved) if (epochStart > saved) { - console.log(`Data in db is outdated, starting from epoch ${epoch}, block #${epochStart}`) + logger.info(`Data in db is outdated, starting from epoch ${epoch}, block #${epochStart}`) blockNumber = epochStart await redis.multi() .set('homeBlock', blockNumber - 1) @@ -57,16 +58,16 @@ async function initialize () { .exec() foreignNonce[epoch] = 0 } else { - console.log('Restoring epoch and block number from local db') + logger.info('Restoring epoch and block number from local db') blockNumber = saved foreignNonce[epoch] = parseInt(await redis.get(`foreignNonce${epoch}`)) || 0 } } async function main () { - console.log(`Watching events in block #${blockNumber}`) + logger.debug(`Watching events in block #${blockNumber}`) if (await web3Home.eth.getBlock(blockNumber) === null) { - console.log('No block') + logger.debug('No block') await new Promise(r => setTimeout(r, 1000)) return } @@ -91,7 +92,7 @@ async function main () { break case 'EpochStart': epoch = event.returnValues.epoch.toNumber() - console.log(`Epoch ${epoch} started`) + logger.info(`Epoch ${epoch} started`) foreignNonce[epoch] = 0 break } @@ -129,7 +130,7 @@ async function sendKeygen (event) { })), { persistent: true }) - console.log('Sent keygen start event') + logger.debug('Sent keygen start event') } function sendKeygenCancelation (event) { @@ -139,7 +140,7 @@ function sendKeygenCancelation (event) { })), { persistent: true }) - console.log('Sent keygen cancellation event') + logger.debug('Sent keygen cancellation event') } async function sendSignFundsTransfer (event) { @@ -154,7 +155,7 @@ async function sendSignFundsTransfer (event) { })), { persistent: true }) - console.log('Sent sign funds transfer event') + logger.debug('Sent sign funds transfer event') foreignNonce[oldEpoch]++ redisTx.incr(`foreignNonce${oldEpoch}`) } @@ -187,8 +188,7 @@ async function sendSign (event) { channel.sendToQueue(signQueue.queue, Buffer.from(msgToQueue), { persistent: true }) - console.log('Sent new sign event') - console.log(msgToQueue) + logger.debug('Sent new sign event: %o', msgToQueue) redisTx.incr(`foreignNonce${epoch}`) foreignNonce[epoch]++ diff --git a/src/oracle/proxy/decode.js b/src/oracle/proxy/decode.js index 4a8c72f..e5efc58 100644 --- a/src/oracle/proxy/decode.js +++ b/src/oracle/proxy/decode.js @@ -225,6 +225,5 @@ module.exports = function (isKeygen, round, value) { const roundNumber = parseInt(round[round.length - 1]) const decoder = (isKeygen ? keygenDecoders : signDecoders)[roundNumber] const decoded = JSON.stringify(decoder(tokenizer)) - console.log(decoded) return decoded } diff --git a/src/oracle/proxy/encode.js b/src/oracle/proxy/encode.js index 8fcaee5..ee350fc 100644 --- a/src/oracle/proxy/encode.js +++ b/src/oracle/proxy/encode.js @@ -137,7 +137,5 @@ module.exports = function (isKeygen, round, value) { break buffers.push(next.value) } - const encoded = Buffer.concat(buffers) - console.log(`Raw data: ${value.length} bytes, encoded data: ${encoded.length} bytes`) - return encoded + return Buffer.concat(buffers) } diff --git a/src/oracle/proxy/index.js b/src/oracle/proxy/index.js index 91523f1..2e049da 100644 --- a/src/oracle/proxy/index.js +++ b/src/oracle/proxy/index.js @@ -9,6 +9,7 @@ const { utils } = require('ethers') const encode = require('./encode') const decode = require('./decode') +const logger = require('./logger') const { HOME_RPC_URL, HOME_BRIDGE_ADDRESS, SIDE_RPC_URL, SIDE_SHARED_DB_ADDRESS, VALIDATOR_PRIVATE_KEY, HOME_CHAIN_ID, @@ -66,14 +67,14 @@ async function main () { homeBlockGasLimit = (await homeWeb3.eth.getBlock('latest', false)).gasLimit sideBlockGasLimit = (await sideWeb3.eth.getBlock('latest', false)).gasLimit - console.log(`My validator address in home and side networks is ${validatorAddress}`) + logger.warn(`My validator address in home and side networks is ${validatorAddress}`) app.listen(8001, () => { - console.log('Proxy is listening on port 8001') + logger.debug('Proxy is listening on port 8001') }) votesProxyApp.listen(8002, () => { - console.log('Votes proxy is listening on port 8001') + logger.debug('Votes proxy is listening on port 8001') }) } @@ -88,8 +89,7 @@ function Err (data) { } async function get (req, res) { - console.log('Get call') - console.log(req.body.key) + logger.debug('Get call, %o', req.body.key) const round = req.body.key.second const uuid = req.body.key.third let from @@ -105,58 +105,59 @@ async function get (req, res) { const data = await sharedDb.methods.getData(from, sideWeb3.utils.sha3(uuid), key).call() if (data.length > 2) { - console.log(data) + logger.trace(`Received encoded data: ${data}`) const decoded = decode(uuid[0] === 'k', round, data) - console.log(decoded) + logger.trace('Decoded data: %o', decoded) res.send(Ok({ key: req.body.key, value: decoded })) } else { setTimeout(() => res.send(Err(null)), 1000) } - console.log('Get end') + logger.debug('Get end') } async function set (req, res) { - console.log('Set call') + logger.debug('Set call') const round = req.body.key.second const uuid = req.body.key.third const to = Number(req.body.key.fourth) const key = homeWeb3.utils.sha3(`${round}_${to}`) - console.log(req.body.value) + logger.trace('Received data: %o', req.body.value) const encoded = encode(uuid[0] === 'k', round, req.body.value) - console.log(encoded.toString('hex')) - + logger.trace(`Encoded data: ${encoded.toString('hex')}`) + logger.trace(`Received data: ${req.body.value.length} bytes, encoded data: ${encoded.length} bytes`) const query = sharedDb.methods.setData(sideWeb3.utils.sha3(uuid), key, encoded) await sideSendQuery(query) res.send(Ok(null)) - console.log('Set end') + logger.debug('Set end') } async function signupKeygen (req, res) { - console.log('SignupKeygen call') + logger.debug('SignupKeygen call') const epoch = (await bridge.methods.nextEpoch().call()).toNumber() const partyId = (await bridge.methods.getNextPartyId(validatorAddress).call()).toNumber() if (partyId === 0) { res.send(Err({ message: 'Not a validator' })) + logger.debug('Not a validator') } else { res.send(Ok({ uuid: `k${epoch}`, number: partyId })) - console.log('SignupKeygen end') + logger.debug('SignupKeygen end') } } async function signupSign (req, res) { - console.log('SignupSign call') + logger.debug('SignupSign call') const hash = sideWeb3.utils.sha3(`0x${req.body.third}`) const query = sharedDb.methods.signupSign(hash) const receipt = await sideSendQuery(query) // Already have signup if (receipt === false) { - console.log('Already have signup') res.send(Ok({ uuid: hash, number: 0 })) + logger.debug('Already have signup') return } @@ -164,29 +165,29 @@ async function signupSign (req, res) { const id = (await sharedDb.methods.getSignupNumber(hash, validators, validatorAddress).call()).toNumber() res.send(Ok({ uuid: hash, number: id })) - console.log('SignupSign end') + logger.debug('SignupSign end') } async function confirmKeygen (req, res) { - console.log('Confirm keygen call') + logger.debug('Confirm keygen call') const { x, y } = req.body[5] const query = bridge.methods.confirmKeygen(`0x${x}`, `0x${y}`) await homeSendQuery(query) res.send() - console.log('Confirm keygen end') + logger.debug('Confirm keygen end') } async function confirmFundsTransfer (req, res) { - console.log('Confirm funds transfer call') + logger.debug('Confirm funds transfer call') const query = bridge.methods.confirmFundsTransfer() await homeSendQuery(query) res.send() - console.log('Confirm funds transfer end') + logger.debug('Confirm funds transfer end') } function sideSendQuery (query) { return lock.acquire('side', async () => { - console.log('Sending query') + logger.debug('Sending query') const encodedABI = query.encodeABI() const tx = { data: encodedABI, @@ -205,13 +206,13 @@ function sideSendQuery (query) { const error = parseError(e.message) const reason = parseReason(e.message) if (error === 'revert' && reason.length) { - console.log(reason) + logger.debug(reason) return false } else if (error === 'out of gas') { - console.log('Out of gas, retrying') + logger.debug('Out of gas, retrying') return true } else { - console.log('Side tx failed, retrying', e.message) + logger.debug('Side tx failed, retrying, %o', e.message) return true } }) @@ -219,12 +220,13 @@ function sideSendQuery (query) { .then(result => { if (result === true) return sideSendQuery(query) - return result + return result !== false }) } function homeSendQuery (query) { return lock.acquire('home', async () => { + logger.debug('Sending query') const encodedABI = query.encodeABI() const tx = { data: encodedABI, @@ -243,13 +245,13 @@ function homeSendQuery (query) { const error = parseError(e.message) const reason = parseReason(e.message) if (error === 'revert' && reason.length) { - console.log(reason) + logger.debug(reason) return false } else if (error === 'out of gas') { - console.log('Out of gas, retrying') + logger.debug('Out of gas, retrying') return true } else { - console.log('Home tx failed, retrying', e.message) + logger.debug('Home tx failed, retrying, %o', e.message) return true } }) @@ -257,7 +259,7 @@ function homeSendQuery (query) { .then(result => { if (result === true) return homeSendQuery(query) - return result + return result !== false }) } @@ -271,76 +273,54 @@ function parseError (message) { return result ? result[0] : '' } -async function voteStartVoting (req, res) { - console.log('Voting for starting new epoch voting process') - const query = bridge.methods.startVoting() +async function sendVote(query, req, res) { try { - await homeSendQuery(query) + if (await homeSendQuery(query)) { + res.send('Voted\n') + logger.info('Voted successfully') + } else { + res.send('Failed\n') + logger.info('Failed to vote') + } } catch (e) { - console.log(e) + logger.debug(e) } - res.send('Voted') - console.log('Voted successfully') +} + +async function voteStartVoting (req, res) { + logger.info('Voting for starting new epoch voting process') + const query = bridge.methods.startVoting() + sendVote(query, req, res) } async function voteStartKeygen (req, res) { - console.log('Voting for starting new epoch keygen') + logger.info('Voting for starting new epoch keygen') const query = bridge.methods.voteStartKeygen() - try { - await homeSendQuery(query) - } catch (e) { - console.log(e) - } - res.send('Voted') - console.log('Voted successfully') + sendVote(query, req, res) } async function voteCancelKeygen (req, res) { - console.log('Voting for cancelling new epoch keygen') + logger.info('Voting for cancelling new epoch keygen') const query = bridge.methods.voteCancelKeygen() - try { - await homeSendQuery(query) - } catch (e) { - console.log(e) - } - res.send('Voted') - console.log('Voted successfully') + sendVote(query, req, res) } async function voteAddValidator (req, res) { - console.log('Voting for adding new validator') + logger.info('Voting for adding new validator') const query = bridge.methods.voteAddValidator(req.params.validator) - try { - await homeSendQuery(query) - } catch (e) { - console.log(e) - } - res.send('Voted') - console.log('Voted successfully') + sendVote(query, req, res) } async function voteChangeThreshold (req, res) { - console.log('Voting for changing threshold') + logger.info('Voting for changing threshold') const query = bridge.methods.voteChangeThreshold(req.params.threshold) - try { - await homeSendQuery(query) - } catch (e) { - console.log(e) - } - res.send('Voted') - console.log('Voted successfully') + sendVote(query, req, res) } async function voteRemoveValidator (req, res) { - console.log('Voting for removing validator') + logger.info('Voting for removing validator') const query = bridge.methods.voteRemoveValidator(req.params.validator) - try { - await homeSendQuery(query) - } catch (e) { - console.log(e) - } - res.send('Voted') - console.log('Voted successfully') + sendVote(query, req, res) } function decodeStatus (status) { @@ -357,7 +337,7 @@ function decodeStatus (status) { } async function info (req, res) { - console.log('Info start') + logger.debug('Info start') const [ x, y, epoch, nextEpoch, threshold, nextThreshold, validators, nextValidators, homeBalance, status ] = await Promise.all([ bridge.methods.getX().call().then(x => new BN(x).toString(16)), bridge.methods.getY().call().then(x => new BN(x).toString(16)), @@ -403,21 +383,21 @@ async function info (req, res) { votesForCancelKeygen, confirmationsForFundsTransfer }) - console.log('Info end') + logger.debug('Info end') } async function transfer (req, res) { - console.log('Transfer start') + logger.info('Transfer start') const { hash, to, value } = req.body if (homeWeb3.utils.isAddress(to)) { - console.log(`Calling transfer to ${to}, ${value} tokens`) + logger.info(`Calling transfer to ${to}, ${value} tokens`) const query = bridge.methods.transfer(hash, to, '0x' + (new BN(value).toString(16))) await homeSendQuery(query) } else { // return funds ? } res.send() - console.log('Transfer end') + logger.info('Transfer end') } function getForeignBalances (address) { diff --git a/src/oracle/shared/db.js b/src/oracle/shared/db.js index 2d222e3..514a486 100644 --- a/src/oracle/shared/db.js +++ b/src/oracle/shared/db.js @@ -1,6 +1,7 @@ const Redis = require('ioredis') -console.log('Connecting to redis') +const logger = require('./logger') +logger.info('Connecting to redis') const redis = new Redis({ port: 6379, @@ -10,11 +11,11 @@ const redis = new Redis({ }) redis.on('connect', () => { - console.log('Connected to redis') + logger.info('Connected to redis') }) redis.on('error', () => { - console.log('Redis error') + logger.warn('Redis error') }) module.exports = redis diff --git a/src/oracle/tss-keygen/keygen.js b/src/oracle/tss-keygen/keygen.js index f189cb9..332b21a 100644 --- a/src/oracle/tss-keygen/keygen.js +++ b/src/oracle/tss-keygen/keygen.js @@ -4,14 +4,16 @@ const crypto = require('crypto') const bech32 = require('bech32') const amqp = require('amqplib') +const logger = require('./logger') + const { RABBITMQ_URL, PROXY_URL } = process.env let currentKeygenEpoch = null async function main () { - console.log('Connecting to RabbitMQ server') + logger.info('Connecting to RabbitMQ server') const connection = await connectRabbit(RABBITMQ_URL) - console.log('Connecting to epoch events queue') + logger.info('Connecting to epoch events queue') const channel = await connection.createChannel() const keygenQueue = await channel.assertQueue('keygenQueue') const cancelKeygenQueue = await channel.assertQueue('cancelKeygenQueue') @@ -19,39 +21,39 @@ async function main () { channel.prefetch(1) channel.consume(keygenQueue.queue, msg => { const { epoch, parties, threshold } = JSON.parse(msg.content) - console.log(`Consumed new epoch event, starting keygen for epoch ${epoch}`) + logger.info(`Consumed new epoch event, starting keygen for epoch ${epoch}`) const keysFile = `/keys/keys${epoch}.store` - console.log('Running ./keygen-entrypoint.sh') + logger.info('Running ./keygen-entrypoint.sh') currentKeygenEpoch = epoch - console.log('Writing params') + logger.debug('Writing params') fs.writeFileSync('./params', JSON.stringify({ parties: parties.toString(), threshold: threshold.toString() })) const cmd = exec.execFile('./keygen-entrypoint.sh', [PROXY_URL, keysFile], async () => { currentKeygenEpoch = null if (fs.existsSync(keysFile)) { - console.log(`Finished keygen for epoch ${epoch}`) + logger.info(`Finished keygen for epoch ${epoch}`) const publicKey = JSON.parse(fs.readFileSync(keysFile))[5] - console.log(`Generated multisig account in binance chain: ${publicKeyToAddress(publicKey)}`) + logger.warn(`Generated multisig account in binance chain: ${publicKeyToAddress(publicKey)}`) - console.log('Sending keys confirmation') + logger.info('Sending keys confirmation') await confirmKeygen(keysFile) } else { - console.log(`Keygen for epoch ${epoch} failed`) + logger.warn(`Keygen for epoch ${epoch} failed`) } - console.log('Ack for keygen message') + logger.debug('Ack for keygen message') channel.ack(msg) }) - cmd.stdout.on('data', data => console.log(data.toString())) - cmd.stderr.on('data', data => console.error(data.toString())) + cmd.stdout.on('data', data => logger.debug(data.toString())) + cmd.stderr.on('data', data => logger.debug(data.toString())) }) channel.consume(cancelKeygenQueue.queue, async msg => { const { epoch } = JSON.parse(msg.content) - console.log(`Consumed new cancel event for epoch ${epoch} keygen`) + logger.info(`Consumed new cancel event for epoch ${epoch} keygen`) if (currentKeygenEpoch === epoch) { - console.log('Cancelling current keygen') + logger.info('Cancelling current keygen') exec.execSync('pkill gg18_keygen || true') } channel.ack(msg) @@ -62,7 +64,7 @@ main() async function connectRabbit (url) { return amqp.connect(url).catch(() => { - console.log('Failed to connect, reconnecting') + logger.debug('Failed to connect, reconnecting') return new Promise(resolve => setTimeout(() => resolve(connectRabbit(url)), 1000) ) diff --git a/src/oracle/tss-sign/signer.js b/src/oracle/tss-sign/signer.js index 6df13a6..7437f8a 100644 --- a/src/oracle/tss-sign/signer.js +++ b/src/oracle/tss-sign/signer.js @@ -6,9 +6,11 @@ const bech32 = require('bech32') const BN = require('bignumber.js') const express = require('express') +const logger = require('./logger') + const app = express() app.get('/restart/:attempt', restart) -app.listen(8001, () => console.log('Listening on 8001')) +app.listen(8001, () => logger.debug('Listening on 8001')) const { RABBITMQ_URL, FOREIGN_URL, PROXY_URL, FOREIGN_ASSET } = process.env const Transaction = require('./tx') @@ -21,9 +23,9 @@ let nextAttempt = null let cancelled async function main () { - console.log('Connecting to RabbitMQ server') + logger.info('Connecting to RabbitMQ server') const connection = await connectRabbit(RABBITMQ_URL) - console.log('Connecting to signature events queue') + logger.info('Connecting to signature events queue') const channel = await connection.createChannel() const signQueue = await channel.assertQueue('signQueue') @@ -31,27 +33,26 @@ async function main () { channel.consume(signQueue.queue, async msg => { const data = JSON.parse(msg.content) - console.log('Consumed sign event') - console.log(data) + logger.info('Consumed sign event: %o', data) const { recipient, value, nonce, epoch, newEpoch, parties, threshold } = data const keysFile = `/keys/keys${epoch}.store` const { address: from, publicKey } = getAccountFromFile(keysFile) if (from === '') { - console.log('Acking message') + logger.info('No keys found, acking message') channel.ack(msg) return } const account = await getAccount(from) - console.log('Writing params') + logger.debug('Writing params') fs.writeFileSync('./params', JSON.stringify({ parties: parties.toString(), threshold: threshold.toString() })) attempt = 1 if (recipient && account.sequence <= nonce) { while (true) { - console.log(`Building corresponding transfer transaction, nonce ${nonce}, recipient ${recipient}`) + logger.info(`Building corresponding transfer transaction, nonce ${nonce}, recipient ${recipient}`) const tx = new Transaction({ from, accountNumber: account.account_number, @@ -63,14 +64,14 @@ async function main () { }) const hash = crypto.createHash('sha256').update(tx.getSignBytes()).digest('hex') - console.log(`Starting signature generation for transaction hash ${hash}`) + logger.info(`Starting signature generation for transaction hash ${hash}`) const done = await sign(keysFile, hash, tx, publicKey) && await waitForAccountNonce(from, nonce + 1) if (done) { break } attempt = nextAttempt ? nextAttempt : attempt + 1 - console.log(`Sign failed, starting next attempt ${attempt}`) + logger.warn(`Sign failed, starting next attempt ${attempt}`) nextAttempt = null await new Promise(resolve => setTimeout(resolve, 1000)) } @@ -79,7 +80,7 @@ async function main () { const { address: to } = getAccountFromFile(newKeysFile) while (to !== '') { - console.log(`Building corresponding transaction for transferring all funds, nonce ${nonce}, recipient ${to}`) + logger.info(`Building corresponding transaction for transferring all funds, nonce ${nonce}, recipient ${to}`) const tx = new Transaction({ from, accountNumber: account.account_number, @@ -92,7 +93,7 @@ async function main () { }) const hash = crypto.createHash('sha256').update(tx.getSignBytes()).digest('hex') - console.log(`Starting signature generation for transaction hash ${hash}`) + logger.info(`Starting signature generation for transaction hash ${hash}`) const done = await sign(keysFile, hash, tx, publicKey) && await waitForAccountNonce(from, nonce + 1) if (done) { @@ -100,14 +101,14 @@ async function main () { break } attempt = nextAttempt ? nextAttempt : attempt + 1 - console.log(`Sign failed, starting next attempt ${attempt}`) + logger.warn(`Sign failed, starting next attempt ${attempt}`) nextAttempt = null await new Promise(resolve => setTimeout(resolve, 1000)) } } else { - console.log('Tx has been already sent') + logger.debug('Tx has been already sent') } - console.log('Acking message') + logger.info('Acking message') channel.ack(msg) }) } @@ -118,31 +119,31 @@ function sign (keysFile, hash, tx, publicKey) { return new Promise(resolve => { const cmd = exec.execFile('./sign-entrypoint.sh', [ PROXY_URL, keysFile, hash ], async (error) => { if (fs.existsSync('signature')) { - console.log('Finished signature generation') + logger.info('Finished signature generation') const signature = JSON.parse(fs.readFileSync('signature')) - console.log(signature) + logger.debug('%o', signature) - console.log('Building signed transaction') + logger.info('Building signed transaction') const signedTx = tx.addSignature(publicKey, { r: signature[1], s: signature[3] }) - console.log('Sending transaction') - console.log(signedTx) + logger.info('Sending transaction') + logger.debug(signedTx) await sendTx(signedTx) resolve(true) } else if (error === null || error.code === 0) { resolve(true) } else { - console.log('Sign failed') + logger.warn('Sign failed') resolve(false) } }) - cmd.stdout.on('data', data => console.log(data.toString())) - cmd.stderr.on('data', data => console.error(data.toString())) + cmd.stdout.on('data', data => logger.debug(data.toString())) + cmd.stderr.on('data', data => logger.debug(data.toString())) }) } function restart (req, res) { - console.log('Cancelling current sign') + logger.info('Cancelling current sign') nextAttempt = req.params.attempt exec.execSync('pkill gg18_sign || true') cancelled = true @@ -151,7 +152,7 @@ function restart (req, res) { function connectRabbit (url) { return amqp.connect(url).catch(() => { - console.log('Failed to connect, reconnecting') + logger.debug('Failed to connect, reconnecting') return new Promise(resolve => setTimeout(() => resolve(connectRabbit(url)), 1000) ) @@ -163,9 +164,9 @@ function confirmFundsTransfer () { } function getAccountFromFile (file) { - console.log(`Reading ${file}`) + logger.debug(`Reading ${file}`) if (!fs.existsSync(file)) { - console.log('No keys found, skipping') + logger.debug('No keys found, skipping') return { address: '' } } const publicKey = JSON.parse(fs.readFileSync(file))[5] @@ -177,25 +178,25 @@ function getAccountFromFile (file) { async function waitForAccountNonce (address, nonce) { cancelled = false - console.log(`Waiting for account ${address} to have nonce ${nonce}`) + logger.info(`Waiting for account ${address} to have nonce ${nonce}`) while (!cancelled) { const sequence = (await getAccount(address)).sequence if (sequence >= nonce) break await new Promise(resolve => setTimeout(resolve, 1000)) - console.log('Waiting for needed account nonce') + logger.debug('Waiting for needed account nonce') } - console.log('Account nonce is OK') + logger.info('Account nonce is OK') return !cancelled } function getAccount (address) { - console.log(`Getting account ${address} data`) + logger.info(`Getting account ${address} data`) return httpClient .get(`/api/v1/account/${address}`) .then(res => res.data) .catch(() => { - console.log('Retrying') + logger.debug('Retrying') return getAccount(address) }) } @@ -209,10 +210,9 @@ function sendTx (tx) { }) .catch(err => { if (err.response.data.message.includes('Tx already exists in cache')) - console.log('Tx already exists in cache') + logger.debug('Tx already exists in cache') else { - console.log(err.response) - console.log('Something failed, restarting') + logger.info('Something failed, restarting: %o', err.response) return new Promise(resolve => setTimeout(() => resolve(sendTx(tx)), 1000)) } }) diff --git a/src/oracle/tss-sign/tx.js b/src/oracle/tss-sign/tx.js index 781c8a0..f5f79dc 100644 --- a/src/oracle/tss-sign/tx.js +++ b/src/oracle/tss-sign/tx.js @@ -2,6 +2,8 @@ const TransactionBnc = require('@binance-chain/javascript-sdk/lib/tx').default const { crypto } = require('@binance-chain/javascript-sdk') const BN = require('bignumber.js') +const logger = require('./logger') + const { FOREIGN_CHAIN_ID } = process.env class Transaction { @@ -69,7 +71,7 @@ class Transaction { const n = new BN('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16) const s = new BN(signature.s, 16) if (s.gt(n.div(2))) { - console.log('Normalizing s') + logger.debug('Normalizing s') signature.s = n.minus(s).toString(16) } const publicKeyEncoded = Buffer.from('eb5ae98721' + (yLast % 2 ? '03' : '02') + padZeros(publicKey.x, 64), 'hex')