diff --git a/lib/bill-math.js b/lib/bill-math.js index d5d4247a..9cc8d47e 100644 --- a/lib/bill-math.js +++ b/lib/bill-math.js @@ -6,13 +6,13 @@ const uuid = require('uuid') // // We can either require canononical denominations for 3+, or try to expand // this algorithm. -exports.makeChange = function makeChange (cartridges, amount) { +exports.makeChange = function makeChange (cassettes, amount) { // Note: Everything here is converted to primitive numbers, // since they're all integers, well within JS number range, // and this is way more efficient in a tight loop. - const small = cartridges[0] - const large = cartridges[1] + const small = cassettes[0] + const large = cassettes[1] const largeDenom = large.denomination const smallDenom = small.denomination @@ -28,8 +28,8 @@ exports.makeChange = function makeChange (cartridges, amount) { if (smallCount > small.count) continue return [ - {count: smallCount, denomination: small.denomination, id: uuid.v4()}, - {count: i, denomination: largeDenom, id: uuid.v4()} + {provisioned: smallCount, denomination: small.denomination, id: uuid.v4()}, + {provisioned: i, denomination: largeDenom, id: uuid.v4()} ] } diff --git a/lib/cash-in-tx.js b/lib/cash-in-tx.js index daff7ce9..144195e7 100644 --- a/lib/cash-in-tx.js +++ b/lib/cash-in-tx.js @@ -169,11 +169,10 @@ function registerTrades (pi, txVector) { function logAction (rec, tx) { const action = { tx_id: tx.id, - action: 'sendCoins', + action: tx.sendCompleted ? 'sendCoins' : 'sendCoinsError', error: rec.error, error_code: rec.errorCode, - tx_hash: rec.txHash, - success: rec.sendConfirmed === true + tx_hash: rec.txHash } const sql = pgp.helpers.insert(action, null, 'cash_in_actions') diff --git a/lib/cash-out-tx.js b/lib/cash-out-tx.js index f17a4c83..4adf9fa2 100644 --- a/lib/cash-out-tx.js +++ b/lib/cash-out-tx.js @@ -18,7 +18,7 @@ module.exports = { const mapValuesWithKey = _.mapValues.convert({cap: false}) -const UPDATEABLE_FIELDS = ['txHash', 'status', 'dispensed', 'notified', 'redeem', +const UPDATEABLE_FIELDS = ['txHash', 'status', 'dispense', 'notified', 'redeem', 'phone', 'error', 'confirmationTime', 'swept'] const STALE_INCOMING_TX_AGE = T.week @@ -27,6 +27,7 @@ const MAX_NOTIFY_AGE = 2 * T.days const MIN_NOTIFY_AGE = 5 * T.minutes function post (tx, pi) { + console.log('DEBUG101: %j', tx) const TransactionMode = pgp.txMode.TransactionMode const isolationLevel = pgp.txMode.isolationLevel const tmSRD = new TransactionMode({tiLevel: isolationLevel.serializable}) @@ -49,19 +50,14 @@ function post (tx, pi) { const [, newTx] = txVector return postProcess(txVector, pi) .then(changes => update(newTx, changes)) - .then(savedTx => { - return logAction(tx, savedTx) - .then(_.constant(savedTx)) - }) }) } -function logError (action, err) { - return logAction({ - action, +function logError (action, err, tx) { + return logAction(action, { error: err.message, error_code: err.name - }) + }, tx) } function mapDispense (tx) { @@ -69,25 +65,23 @@ function mapDispense (tx) { if (_.isEmpty(bills)) return {} - const dispense = { + return { provisioned_1: bills[0].provisioned, provisioned_2: bills[1].provisioned, - dispensed_1: bills[0].actualDispense, - dispensed_2: bills[1].actualDispense, + dispensed_1: bills[0].dispensed, + dispensed_2: bills[1].dispensed, rejected_1: bills[0].rejected, rejected_2: bills[1].rejected, denomination_1: bills[0].denomination, denomination_2: bills[1].denomination } - - return dispense } function logDispense (tx) { - const baseRec = {error: tx.error, errorCode: tx.errorCode} + const baseRec = {error: tx.error, error_code: tx.errorCode} const rec = _.merge(mapDispense(tx), baseRec) - - return logAction('dispense', rec, tx) + const action = tx.dispenseConfirmed ? 'dispense' : 'dispenseError' + return logAction(action, rec, tx) } function logActionById (action, _rec, txId) { @@ -98,9 +92,10 @@ function logActionById (action, _rec, txId) { } function logAction (action, _rec, tx) { - const rec = _.assign(_rec, {action, tx_id: tx.id, redeem: tx.redeem}) + const rec = _.assign(_rec, {action, tx_id: tx.id, redeem: !!tx.redeem}) const sql = pgp.helpers.insert(rec, null, 'cash_out_actions') + console.log('DEBUG110: %j', sql) return db.none(sql) .then(_.constant(tx)) } @@ -217,11 +212,11 @@ function preProcess (oldTx, newTx, pi) { .then(_.set('toAddress', _, newTxHd)) }) .then(addressedTx => { - const rec = {toAddress: addressedTx.toAddress} + const rec = {to_address: addressedTx.toAddress} return logAction('provisionAddress', rec, addressedTx) }) .catch(err => { - return logError('provisionAddress', err) + return logError('provisionAddress', err, newTx) .then(() => { throw err }) }) } @@ -234,7 +229,9 @@ function preProcess (oldTx, newTx, pi) { return logAction(updatedTx.status, {}, updatedTx) } - if (_.isNil(oldTx.dispenseConfirmed) && _.isBoolean(updatedTx.dispenseConfirmed)) { + console.log('DEBUG120: %j', [oldTx, updatedTx]) + if (!oldTx.dispenseConfirmed && updatedTx.dispenseConfirmed) { + console.log('DEBUG121') return logDispense(updatedTx) .then(pi.updateCassettes(updatedTx)) } @@ -254,18 +251,24 @@ function preProcess (oldTx, newTx, pi) { function postProcess (txVector, pi) { const [, newTx] = txVector - if (newTx.dispensed && !newTx.bills) { - return pi.buildCartridges() - .then(cartridges => { + if (newTx.dispense && !newTx.bills) { + return pi.buildCassettes() + .then(cassettes => { pi.sell(newTx) - return _.set('bills', billMath.makeChange(cartridges.cartridges, newTx.fiat), newTx) + return _.set('bills', billMath.makeChange(cassettes.cassettes, newTx.fiat), newTx) }) .then(tx => { - const rec = {provisioned_1: tx.bills[0], provisioned_2: tx.bills[1]} + const rec = { + provisioned_1: tx.bills[0].provisioned, + provisioned_2: tx.bills[1].provisioned, + denomination_1: tx.bills[0].denomination, + denomination_2: tx.bills[1].denomination + } + return logAction('provisionNotes', rec, tx) }) .catch(err => { - return logError('provisionNotes', err) + return logError('provisionNotesError', err, newTx) .then(() => { throw err }) }) } @@ -333,7 +336,7 @@ function monitorUnnotified (settings) { const sql = `select * from cash_out_txs where ((extract(epoch from (now() - created))) * 1000)<$1 - and notified=$2 and dispensed=$3 + and notified=$2 and dispense=$3 and phone is not null and status in ('instant', 'confirmed') and (redeem=$4 or ((extract(epoch from (now() - created))) * 1000)>$5)` @@ -349,7 +352,7 @@ function cancel (txId) { const updateRec = { 'dispense_time': 'now()^', error: 'Operator cancel', - dispensed: true + dispense: true } return Promise.resolve() diff --git a/lib/plugins.js b/lib/plugins.js index f1f1deb6..b89d0f13 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -72,47 +72,47 @@ function plugins (settings, deviceId) { return balances } - function buildCartridges () { + function buildCassettes () { const config = configManager.machineScoped(deviceId, settings.config) if (!config.cashOutEnabled) return Promise.resolve() - const cartridges = [ config.topCashOutDenomination, + const cassettes = [ config.topCashOutDenomination, config.bottomCashOutDenomination ] - const virtualCartridges = [config.virtualCashOutDenomination] + const virtualCassettes = [config.virtualCashOutDenomination] - return dbm.cartridgeCounts(deviceId) + return dbm.cassetteCounts(deviceId) .then(rec => { if (argv.cassettes) { const counts = argv.cassettes.split(',') return { - cartridges: [ + cassettes: [ { - denomination: parseInt(cartridges[0], 10), + denomination: parseInt(cassettes[0], 10), count: parseInt(counts[0], 10) }, { - denomination: parseInt(cartridges[1], 10), + denomination: parseInt(cassettes[1], 10), count: parseInt(counts[1], 10) } ], - virtualCartridges + virtualCassettes } } return { - cartridges: [ + cassettes: [ { - denomination: parseInt(cartridges[0], 10), + denomination: parseInt(cassettes[0], 10), count: parseInt(rec.counts[0], 10) }, { - denomination: parseInt(cartridges[1], 10), + denomination: parseInt(cassettes[1], 10), count: parseInt(rec.counts[1], 10) } ], - virtualCartridges + virtualCassettes } }) } @@ -138,20 +138,20 @@ function plugins (settings, deviceId) { const currentConfigVersionPromise = fetchCurrentConfigVersion() const promises = [ - buildCartridges(), + buildCassettes(), pingPromise, currentConfigVersionPromise ].concat(tickerPromises, balancePromises) return Promise.all(promises) .then(arr => { - const cartridges = arr[0] + const cassettes = arr[0] const currentConfigVersion = arr[2] const tickers = arr.slice(3, cryptoCodes.length + 3) const balances = arr.slice(cryptoCodes.length + 3) return { - cartridges, + cassettes, rates: buildRates(tickers), balances: buildBalances(balances), currentConfigVersion @@ -194,10 +194,10 @@ function plugins (settings, deviceId) { function dispenseAck (tx) { const config = configManager.machineScoped(deviceId, settings.config) - const cartridges = [ config.topCashOutDenomination, + const cassettes = [ config.topCashOutDenomination, config.bottomCashOutDenomination ] - return dbm.addDispense(deviceId, tx, cartridges) + return dbm.addDispense(deviceId, tx, cassettes) } function fiatBalance (fiatCode, cryptoCode) { @@ -517,9 +517,9 @@ function plugins (settings, deviceId) { // However, we should make all config changes atomic in the future. const config = configManager.machineScoped(deviceId, settings.config) const topCashOutDenomination = config.topCashOutDenomination - - (tx.bills[0].actualDispense + tx.bills[0].rejected) + (tx.bills[0].dispensed + tx.bills[0].rejected) const bottomCashOutDenomination = config.bottomCashOutDenomination - - (tx.bills[1].actualDispense + tx.bills[1].rejected) + (tx.bills[1].dispensed + tx.bills[1].rejected) const newFields = [ { @@ -575,7 +575,7 @@ function plugins (settings, deviceId) { sweepHd, sendMessage, checkBalances, - buildCartridges, + buildCassettes, updateCassettes, buy, sell diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index 53c0a1af..1a515ca4 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -23,7 +23,7 @@ exports.recordDeviceEvent = function recordDeviceEvent (deviceId, event) { return db.none(sql, values) } -exports.cartridgeCounts = function cartridgeCounts (deviceId) { +exports.cassetteCounts = function cassetteCounts (deviceId) { const sql = 'SELECT cassette1, cassette2 FROM devices ' + 'WHERE device_id=$1' diff --git a/lib/route-helpers.js b/lib/route-helpers.js index 8571120c..02b1a0f7 100644 --- a/lib/route-helpers.js +++ b/lib/route-helpers.js @@ -49,7 +49,7 @@ function toObj (row) { function fetchPhoneTx (phone) { const sql = `select * from cash_out_txs - where phone=$1 and dispensed=$2 + where phone=$1 and dispense=$2 and (extract(epoch from (coalesce(confirmation_time, now()) - created))) * 1000 < $3` const values = [phone, false, TRANSACTION_EXPIRATION] diff --git a/lib/routes.js b/lib/routes.js index 105ec46c..4d7e8fad 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -38,7 +38,7 @@ function poll (req, res, next) { return pi.pollQueries(deviceTime, req.query) .then(results => { - const cartridges = results.cartridges + const cassettes = results.cassettes const reboot = pid && reboots[deviceId] && reboots[deviceId] === pid const langs = config.machineLanguages @@ -58,7 +58,7 @@ function poll (req, res, next) { txLimit: config.cashInTransactionLimit, idVerificationEnabled: config.idVerificationEnabled, smsVerificationEnabled: config.smsVerificationEnabled, - cartridges, + cassettes, twoWayMode: config.cashOutEnabled, zeroConfLimit: config.zeroConfLimit, fiatTxLimit: config.cashOutTransactionLimit, diff --git a/migrations/027-tx_errors.js b/migrations/027-tx_errors.js index c0eb4156..374bcdb4 100644 --- a/migrations/027-tx_errors.js +++ b/migrations/027-tx_errors.js @@ -4,12 +4,11 @@ exports.up = function (next) { var sql = [ `create table cash_in_actions ( id serial primary key, - tx_id uuid references cash_in_txs not null, + tx_id uuid not null, action text not null, error text, error_code text, tx_hash text, - success boolean not null, created timestamptz not null default now() )` ] diff --git a/migrations/028-cash_out_actions.js b/migrations/028-cash_out_actions.js index 524efd6b..4c19beaa 100644 --- a/migrations/028-cash_out_actions.js +++ b/migrations/028-cash_out_actions.js @@ -4,13 +4,12 @@ exports.up = function (next) { var sql = [ `create table cash_out_actions ( id serial primary key, - tx_id uuid references cash_out_txs not null, + tx_id uuid not null, action text not null, to_address text, error text, error_code text, tx_hash text, - success boolean not null, provisioned_1 integer, provisioned_2 integer, dispensed_1 integer, @@ -30,7 +29,8 @@ exports.up = function (next) { 'alter table cash_out_txs drop column denomination_1', 'alter table cash_out_txs drop column denomination_2', 'alter table cash_out_txs drop column dispense_error', - 'alter table cash_out_txs add column dispense_confirmed boolean default false' + 'alter table cash_out_txs add column dispense_confirmed boolean default false', + 'alter table cash_out_txs rename column dispensed to dispense' ] db.multi(sql, next) }