feat: add crypto reservation for batched transaction

This commit is contained in:
Sérgio Salgado 2021-11-24 19:09:15 +00:00
parent 0132227251
commit 008dd3e9f6
4 changed files with 49 additions and 24 deletions

View file

@ -17,7 +17,7 @@ const NodeCache = require('node-cache')
const util = require('util') const util = require('util')
const db = require('./db') const db = require('./db')
const state = require('./middlewares/state') const state = require('./middlewares/state')
const batching = require('./tx-batching') const processBatches = require('./tx-batching-processing')
const INCOMING_TX_INTERVAL = 30 * T.seconds const INCOMING_TX_INTERVAL = 30 * T.seconds
const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds
@ -216,7 +216,7 @@ function doPolling (schema) {
} }
addToQueue(cashOutTx.monitorUnnotified, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings) addToQueue(cashOutTx.monitorUnnotified, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings)
addToQueue(cashInTx.monitorPending, PENDING_INTERVAL, schema, QUEUE.FAST, settings) addToQueue(cashInTx.monitorPending, PENDING_INTERVAL, schema, QUEUE.FAST, settings)
addToQueue(batching.processBatches, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings, TRANSACTION_BATCH_LIFECYCLE) addToQueue(processBatches, UNNOTIFIED_INTERVAL, schema, QUEUE.FAST, settings, TRANSACTION_BATCH_LIFECYCLE)
addToQueue(pi().sweepHd, SWEEP_HD_INTERVAL, schema, QUEUE.FAST, settings) addToQueue(pi().sweepHd, SWEEP_HD_INTERVAL, schema, QUEUE.FAST, settings)
addToQueue(pi().pong, PONG_INTERVAL, schema, QUEUE.FAST) addToQueue(pi().pong, PONG_INTERVAL, schema, QUEUE.FAST)
addToQueue(pi().clearOldLogs, LOGS_CLEAR_INTERVAL, schema, QUEUE.SLOW) addToQueue(pi().clearOldLogs, LOGS_CLEAR_INTERVAL, schema, QUEUE.SLOW)

View file

@ -0,0 +1,29 @@
const _ = require('lodash/fp')
const txBatching = require('./tx-batching')
const wallet = require('./wallet')
function submitBatch (settings, batch) {
txBatching.getBatchTransactions(batch)
.then(txs => {
wallet.sendCoinsBatch(settings, txs, batch.crypto_code)
.then(res => txBatching.confirmSentBatch(batch, res))
.catch(err => txBatching.setErroredBatch(batch, err.message))
})
}
function processBatches (settings, lifecycle) {
return txBatching.getBatchesByStatus(['open'])
.then(batches => {
_.each(batch => {
const elapsedMS = batch.time_elapsed * 1000
if (elapsedMS >= lifecycle) {
return txBatching.closeTransactionBatch(batch)
.then(() => submitBatch(settings, batch))
}
}, batches)
})
}
module.exports = processBatches

View file

@ -4,7 +4,6 @@ const uuid = require('uuid')
const BN = require('./bn') const BN = require('./bn')
const db = require('./db') const db = require('./db')
const wallet = require('./wallet')
function addTransactionToBatch (tx) { function addTransactionToBatch (tx) {
const sql = `SELECT * FROM transaction_batches WHERE crypto_code=$1 AND status='open' ORDER BY created_at DESC LIMIT 1` const sql = `SELECT * FROM transaction_batches WHERE crypto_code=$1 AND status='open' ORDER BY created_at DESC LIMIT 1`
@ -57,30 +56,23 @@ function getBatchesByStatus (statuses) {
return db.manyOrNone(sql, [_.map(pgp.as.text, statuses).join(',')]) return db.manyOrNone(sql, [_.map(pgp.as.text, statuses).join(',')])
} }
function submitBatch (settings, batch) { function getOpenBatchCryptoValue (cryptoCode) {
getBatchTransactions(batch) const sql = `SELECT * FROM transaction_batches WHERE crypto_code=$1 AND status='open' ORDER BY created_at DESC LIMIT 1`
.then(txs => {
wallet.sendCoinsBatch(settings, txs, batch.crypto_code)
.then(res => confirmSentBatch(batch, res))
.catch(err => setErroredBatch(batch, err.message))
})
}
function processBatches (settings, lifecycle) { return db.oneOrNone(sql, [cryptoCode])
return getBatchesByStatus(['open']) .then(batch => {
.then(batches => { if (_.isNil(batch)) return Promise.resolve([])
_.each(batch => { return db.any(`SELECT * FROM cash_in_txs WHERE batch_id=$1`, [batch.id])
const elapsedMS = batch.time_elapsed * 1000
if (elapsedMS >= lifecycle) {
return closeTransactionBatch(batch)
.then(() => submitBatch(settings, batch))
}
}, batches)
}) })
.then(txs => _.reduce((acc, tx) => acc.plus(tx.cash_in_fee_crypto).plus(tx.crypto_atoms), BN(0), txs))
} }
module.exports = { module.exports = {
addTransactionToBatch, addTransactionToBatch,
processBatches closeTransactionBatch,
confirmSentBatch,
setErroredBatch,
getBatchTransactions,
getBatchesByStatus,
getOpenBatchCryptoValue
} }

View file

@ -13,6 +13,8 @@ const ph = require('./plugin-helper')
const layer2 = require('./layer2') const layer2 = require('./layer2')
const httpError = require('./route-helpers').httpError const httpError = require('./route-helpers').httpError
const logger = require('./logger') const logger = require('./logger')
const { getOpenBatchCryptoValue } = require('./tx-batching')
const BN = require('./bn')
const FETCH_INTERVAL = 5000 const FETCH_INTERVAL = 5000
const INSUFFICIENT_FUNDS_CODE = 570 const INSUFFICIENT_FUNDS_CODE = 570
@ -46,7 +48,9 @@ const lastBalance = {}
function _balance (settings, cryptoCode) { function _balance (settings, cryptoCode) {
return fetchWallet(settings, cryptoCode) return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.balance(r.account, cryptoCode, settings, r.operatorId)) .then(r => r.wallet.balance(r.account, cryptoCode, settings, r.operatorId))
.then(balance => ({ balance, timestamp: Date.now() })) .then(balance => Promise.all([balance, supportsBatching(settings, cryptoCode)]))
.then(([balance, supportsBatching]) => Promise.all([balance, supportsBatching ? getOpenBatchCryptoValue(cryptoCode) : Promise.resolve(BN(0))]))
.then(([balance, reservedBalance]) => ({ balance: balance.minus(reservedBalance), reservedBalance, timestamp: Date.now() }))
.then(r => { .then(r => {
lastBalance[cryptoCode] = r lastBalance[cryptoCode] = r
return r return r