fix cash-in-txs updating

This commit is contained in:
Josh Harvey 2017-04-25 13:29:53 +03:00
parent fc33339997
commit 6a6075c120
3 changed files with 56 additions and 21 deletions

View file

@ -9,8 +9,6 @@ const mapValuesWithKey = _.mapValues.convert({cap: false})
module.exports = {post, monitorPending} module.exports = {post, monitorPending}
const UPDATEABLE_FIELDS = ['fee', 'txHash', 'phone', 'error', 'send',
'cryptoAtoms', 'fiat', 'timedout']
const PENDING_INTERVAL = '1 day' const PENDING_INTERVAL = '1 day'
const MAX_PENDING = 10 const MAX_PENDING = 10
@ -43,10 +41,11 @@ function post (tx, pi) {
return db.tx(transaction) return db.tx(transaction)
.then(txVector => { .then(txVector => {
const [oldTx, newTx, newBills] = txVector const [oldTx,, newBills] = txVector
const oldBills = oldTx ? oldTx.bills : [] const oldBills = oldTx ? oldTx.bills : []
return postProcess(txVector, pi) return postProcess(txVector, pi)
.then(changes => update(newTx, changes)) .then(changes => update(oldTx, changes))
.then(tx => _.merge({bills: _.concat(oldBills, newBills)}, tx)) .then(tx => _.merge({bills: _.concat(oldBills, newBills)}, tx))
}) })
} }
@ -57,17 +56,54 @@ function nilEqual (a, b) {
return undefined return undefined
} }
function isMonotonic (oldField, newField, fieldKey) {
if (_.isNil(newField)) return false
if (_.isBoolean(oldField)) return oldField === newField || !oldField
if (oldField.isBigNumber) return oldField.lte(newField)
if (_.isNumber(oldField)) return oldField <= newField
throw new Error(`Unexpected value: ${oldField}`)
}
function ensureRatchet (oldField, newField, fieldKey) {
const monotonic = ['cryptoAtoms', 'fiat', 'send', 'sendConfirmed', 'operatorCompleted', 'timedout']
const free = ['sendPending', 'error', 'errorCode']
if (_.isNil(oldField)) return true
if (_.includes(fieldKey, monotonic)) return isMonotonic(oldField, newField, fieldKey)
if (_.includes(fieldKey, free)) {
if (_.isNil(newField)) return false
return true
}
logger.error('This field [%s] should never change', fieldKey)
logger.error('oldField: %j', oldField)
logger.error('newField: %j', newField)
throw new Error(`This field [${fieldKey}] should never change`)
}
function diff (oldTx, newTx) { function diff (oldTx, newTx) {
let updatedTx = {} let updatedTx = {}
UPDATEABLE_FIELDS.forEach(fieldKey => { if (!oldTx) throw new Error('oldTx must not be null')
if (oldTx && _.isEqualWith(nilEqual, oldTx[fieldKey], newTx[fieldKey])) return if (!newTx) throw new Error('newTx must not be null')
// We never null out an existing field _.forEach(fieldKey => {
if (oldTx && _.isNil(newTx[fieldKey])) return const oldField = oldTx[fieldKey]
const newField = newTx[fieldKey]
if (fieldKey === 'bills') return
if (_.isEqualWith(nilEqual, oldField, newField)) return
updatedTx[fieldKey] = newTx[fieldKey] if (!ensureRatchet(oldField, newField, fieldKey)) {
}) logger.warn('Value from lamassu-machine would violate ratchet [%s]', fieldKey)
logger.warn('Old tx: %j', oldTx)
logger.warn('New tx: %j', newTx)
return
}
updatedTx[fieldKey] = newField
}, _.keys(newTx))
return updatedTx return updatedTx
} }
@ -85,6 +121,11 @@ function toObj (row) {
return return
} }
if (key === 'device_time') {
newObj[objKey] = parseInt(row[key], 10)
return
}
newObj[objKey] = row[key] newObj[objKey] = row[key]
}) })
@ -128,14 +169,14 @@ function insertNewBills (billRows, tx) {
.then(() => bills) .then(() => bills)
} }
function upsert (oldTx, tx) { function upsert (oldTx, newTx) {
if (!oldTx) { if (!oldTx) {
return insert(tx) return insert(newTx)
.then(newTx => [oldTx, newTx]) .then(tx => [oldTx, tx])
} }
return update(tx, diff(oldTx, tx)) return update(oldTx, diff(oldTx, newTx))
.then(newTx => [oldTx, newTx]) .then(tx => [oldTx, tx])
} }
function insert (tx) { function insert (tx) {
@ -235,7 +276,6 @@ function monitorPending (settings) {
} }
return db.any(sql, [PENDING_INTERVAL, MAX_PENDING]) return db.any(sql, [PENDING_INTERVAL, MAX_PENDING])
.then(_.tap(console.log))
.then(rows => Promise.all(_.map(processPending, rows))) .then(rows => Promise.all(_.map(processPending, rows)))
.catch(logger.error) .catch(logger.error)
} }

View file

@ -17,7 +17,6 @@ function sendMessage (account, rec) {
from: account.fromNumber from: account.fromNumber
} }
return client.sendMessage(opts) return client.sendMessage(opts)
.catch(err => { .catch(err => {
if (_.includes(err.code, BAD_NUMBER_CODES)) { if (_.includes(err.code, BAD_NUMBER_CODES)) {

View file

@ -44,15 +44,11 @@ function balance (settings, cryptoCode) {
} }
function sendCoins (settings, toAddress, cryptoAtoms, cryptoCode) { function sendCoins (settings, toAddress, cryptoAtoms, cryptoCode) {
console.log('DEBUG40')
return fetchWallet(settings, cryptoCode) return fetchWallet(settings, cryptoCode)
.then(r => { .then(r => {
console.log('DEBUG41')
return r.wallet.sendCoins(r.account, toAddress, cryptoAtoms, cryptoCode) return r.wallet.sendCoins(r.account, toAddress, cryptoAtoms, cryptoCode)
.then(res => { .then(res => {
console.log('DEBUG42')
mem.clear(module.exports.balance) mem.clear(module.exports.balance)
console.log('DEBUG43: %j', res)
return res return res
}) })
}) })