feat: add batch_time and batched to cash_in_txs

feat: add batched flag to clear tx to send
feat: add batch information to front-end
feat: change transaction sending info on batch sending
fix: batching support function added to all wallet plugins
fix: mock-wallet batching check
feat: send machine information about batchable coins
This commit is contained in:
Sérgio Salgado 2021-05-24 19:32:45 +01:00
parent 8289c55acf
commit 00c38ea721
8 changed files with 43 additions and 19 deletions

View file

@ -102,7 +102,7 @@ function diff (oldTx, newTx) {
} }
function ensureRatchet (oldField, newField, fieldKey) { function ensureRatchet (oldField, newField, fieldKey) {
const monotonic = ['cryptoAtoms', 'fiat', 'cashInFeeCrypto', 'send', 'sendConfirmed', 'operatorCompleted', 'timedout', 'txVersion'] const monotonic = ['cryptoAtoms', 'fiat', 'cashInFeeCrypto', 'send', 'sendConfirmed', 'operatorCompleted', 'timedout', 'txVersion', 'batched']
const free = ['sendPending', 'error', 'errorCode', 'customerId'] const free = ['sendPending', 'error', 'errorCode', 'customerId']
if (_.isNil(oldField)) return true if (_.isNil(oldField)) return true
@ -138,11 +138,11 @@ function nilEqual (a, b) {
function isClearToSend (oldTx, newTx) { function isClearToSend (oldTx, newTx) {
const now = Date.now() const now = Date.now()
return newTx.send && return (newTx.send || newTx.batched) &&
(!oldTx || (!oldTx.sendPending && !oldTx.sendConfirmed)) && (!oldTx || (!oldTx.sendPending && !oldTx.sendConfirmed)) &&
(newTx.created > now - PENDING_INTERVAL_MS) (newTx.created > now - PENDING_INTERVAL_MS)
} }
function isFinalTxStage (txChanges) { function isFinalTxStage (txChanges) {
return txChanges.send return txChanges.send || txChanges.batched
} }

View file

@ -120,15 +120,27 @@ function postProcess (r, pi, isBlacklisted, addressReuse, failedWalletScore) {
if (!cashInLow.isClearToSend(r.dbTx, r.tx)) return Promise.resolve({}) if (!cashInLow.isClearToSend(r.dbTx, r.tx)) return Promise.resolve({})
return pi.sendCoins(r.tx) return pi.sendCoins(r.tx)
.then(txObj => ({ .then(txObj => {
txHash: txObj.txid, if (txObj.batched) {
fee: txObj.fee, return {
sendConfirmed: true, batched: true,
sendTime: 'now()^', batchTime: 'now()^',
sendPending: false, sendPending: true,
error: null, error: null,
errorCode: null errorCode: null
})) }
}
return {
txHash: txObj.txid,
fee: txObj.fee,
sendConfirmed: true,
sendTime: 'now()^',
sendPending: false,
error: null,
errorCode: null
}
})
.catch(err => { .catch(err => {
// Important: We don't know what kind of error this is // Important: We don't know what kind of error this is
// so not safe to assume that funds weren't sent. // so not safe to assume that funds weren't sent.

View file

@ -45,6 +45,8 @@ const typeDef = gql`
discount: Int discount: Int
txCustomerPhotoPath: String txCustomerPhotoPath: String
txCustomerPhotoAt: Date txCustomerPhotoAt: Date
batched: Boolean
batchTime: Date
} }
type Filter { type Filter {

View file

@ -260,7 +260,8 @@ function plugins (settings, deviceId) {
const configVersion = arr[2] const configVersion = arr[2]
const tz = arr[3] const tz = arr[3]
const cryptoCodesCount = cryptoCodes.length const cryptoCodesCount = cryptoCodes.length
const batchableCoins = arr.slice(4, cryptoCodesCount + 4) const batchableCoinsRes = arr.slice(4, cryptoCodesCount + 4)
const batchableCoins = batchableCoinsRes.map(it => ({ batchable: it }))
const tickers = arr.slice(cryptoCodesCount + 4, 2 * cryptoCodesCount + 4) const tickers = arr.slice(cryptoCodesCount + 4, 2 * cryptoCodesCount + 4)
const balances = arr.slice(2 * cryptoCodesCount + 4, 3 * cryptoCodesCount + 4) const balances = arr.slice(2 * cryptoCodesCount + 4, 3 * cryptoCodesCount + 4)
const testNets = arr.slice(3 * cryptoCodesCount + 4, arr.length - 1) const testNets = arr.slice(3 * cryptoCodesCount + 4, arr.length - 1)
@ -272,7 +273,7 @@ function plugins (settings, deviceId) {
cassettes, cassettes,
rates: buildRates(tickers), rates: buildRates(tickers),
balances: buildBalances(balances), balances: buildBalances(balances),
coins: _.zipWith(_.assign, coinsWithoutRate, tickers), coins: _.zipWith(_.assign, _.zipWith(_.assign, coinsWithoutRate, tickers), batchableCoins),
configVersion, configVersion,
areThereAvailablePromoCodes, areThereAvailablePromoCodes,
timezone: tz timezone: tz

View file

@ -2,6 +2,7 @@ const _ = require('lodash/fp')
const pgp = require('pg-promise')() const pgp = require('pg-promise')()
const uuid = require('uuid') const uuid = require('uuid')
const BN = require('./bn')
const db = require('./db') const db = require('./db')
const wallet = require('./wallet') const wallet = require('./wallet')
@ -17,10 +18,13 @@ function closeTransactionBatch (batch) {
return db.none(sql, [batch.id]) return db.none(sql, [batch.id])
} }
function confirmSentBatch (batch) { function confirmSentBatch (batch, tx) {
const sql = `UPDATE transaction_batches SET status='sent', error_message=NULL WHERE id=$1` return db.tx(t => {
const q1 = t.none(`UPDATE transaction_batches SET status='sent', error_message=NULL WHERE id=$1`, [batch.id])
const q2 = t.none(`UPDATE cash_in_txs SET tx_hash=$1, fee=$2, send=true, send_confirmed=true, send_time=now(), send_pending=false, error=NULL, error_code=NULL WHERE batch_id=$3`, [tx.txid, tx.fee.toString(), batch.id])
return db.none(sql, [batch.id]) return t.batch([q1, q2])
})
} }
function setErroredBatch (batch, errorMsg) { function setErroredBatch (batch, errorMsg) {
@ -57,7 +61,7 @@ function submitBatch (settings, batch) {
getBatchTransactions(batch) getBatchTransactions(batch)
.then(txs => { .then(txs => {
wallet.sendCoinsBatch(settings, txs, batch.crypto_code) wallet.sendCoinsBatch(settings, txs, batch.crypto_code)
.then(() => confirmSentBatch(batch)) .then(res => confirmSentBatch(batch, res))
.catch(err => setErroredBatch(batch, err.message)) .catch(err => setErroredBatch(batch, err.message))
}) })
} }

View file

@ -11,7 +11,9 @@ exports.up = function (next) {
closed_at TIMESTAMPTZ, closed_at TIMESTAMPTZ,
error_message TEXT error_message TEXT
)`, )`,
`ALTER TABLE cash_in_txs ADD COLUMN batch_id UUID REFERENCES transaction_batches(id)` `ALTER TABLE cash_in_txs ADD COLUMN batch_id UUID REFERENCES transaction_batches(id)`,
`ALTER TABLE cash_in_txs ADD COLUMN batched BOOLEAN NOT NULL DEFAULT false`,
`ALTER TABLE cash_in_txs ADD COLUMN batch_time TIMESTAMPTZ`
] ]
db.multi(sql, next) db.multi(sql, next)

View file

@ -110,6 +110,8 @@ const GET_TRANSACTIONS = gql`
discount discount
customerId customerId
isAnonymous isAnonymous
batched
batchTime
} }
} }
` `

View file

@ -11,6 +11,7 @@ const getCashInStatus = it => {
if (it.hasError) return 'Error' if (it.hasError) return 'Error'
if (it.sendConfirmed) return 'Sent' if (it.sendConfirmed) return 'Sent'
if (it.expired) return 'Expired' if (it.expired) return 'Expired'
if (it.batched) return 'Batched'
return 'Pending' return 'Pending'
} }