From 996ebd395bf9f1aff04db8e232e59cb5d586b67b Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Tue, 10 May 2016 14:03:13 +0300 Subject: [PATCH] improve transaction expiration --- lib/plugins.js | 8 +++++--- lib/postgresql_interface.js | 32 +++++++++++++++++++++----------- migrations/008-add-two-way.js | 1 + 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/lib/plugins.js b/lib/plugins.js index d5c64ee9..f8b55e36 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -25,6 +25,7 @@ var STALE_INCOMING_TX_AGE = 7 * 24 * 60 * 60 * 1000 var UNNOTIFIED_INTERVAL = 60 * 1000 var MAX_NOTIFY_AGE = 48 * 60 * 60 * 1000 var MIN_NOTIFY_AGE = 5 * 60 * 1000 +var TRANSACTION_EXPIRATION = 48 * 60 * 60 * 1000 if (argv.timeout) PENDING_TIMEOUT = argv.timeout / 1000 @@ -457,8 +458,9 @@ function processTxStatus (tx) { var status = res.status if (tx.status === status) return resolve() - - db.updateTxStatus(tx, status, function (_err) { + const confirm = (status === 'instant' && tx.status !== 'confirmed') || + (status === 'confirmed' && tx.status !== 'instant') + db.updateTxStatus(tx, status, confirm, function (_err) { if (_err) logger.error(err) resolve() }) @@ -804,7 +806,7 @@ exports.registerRedeem = function registerRedeem (session) { } exports.fetchPhoneTx = function fetchPhoneTx (phone) { - db.fetchPhoneTxs(phone) + db.fetchPhoneTxs(phone, TRANSACTION_EXPIRATION) .then(txs => { const authorizedTxs = txs.filter(tx => tx.authorized) if (authorizedTxs.length > 0) { diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index 8177491e..ed942af3 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -527,8 +527,8 @@ function normalizeTxs (txs) { exports.fetchPhoneTxs = function fetchPhoneTxs (phone, dispenseTimeout) { var sql = 'SELECT * FROM transactions ' + 'WHERE phone=$1 AND dispensed=$2 ' + - 'AND (EXTRACT(EPOCH FROM (now() - created))) * 1000 < $1 ' + - 'AND stage=$3 AND authority=$4 AND incoming=$5' + 'AND (EXTRACT(EPOCH FROM (COALESCE(confirmation_time, now()) - created))) * 1000 < $3 ' + + 'AND stage=$4 AND authority=$5 AND incoming=$6' return new Promise((resolve, reject) => { connect(function (cerr, client, done) { @@ -713,19 +713,29 @@ exports.fetchUnnotifiedTxs = function fetchUnnotifiedTxs (age, waitPeriod, cb) { }) } -exports.updateTxStatus = function updateTxStatus (tx, status, cb) { - var sql = 'UPDATE transactions SET status=$1 WHERE id=$2' - - connect(function (cerr, client, done) { - if (cerr) return cb(cerr) - var values = [status, tx.id] - query(client, sql, values, function (err) { - done(err) - cb(err) +function pquery (sql, values) { + return new Promise((resolve, reject) => { + connect(function (cerr, client, done) { + if (cerr) return reject(cerr) + query(client, sql, values, function (err, results) { + done(err) + if (err) return reject(err) + resolve(results) + }) }) }) } +exports.updateTxStatus = function updateTxStatus (tx, status, confirm) { + var sql = confirm + ? 'UPDATE transactions SET status=$1, confirmation_time=now() WHERE id=$2' + : 'UPDATE transactions SET status=$1 WHERE id=$2' + + var values = [status, tx.id] + + return pquery(sql, values) +} + exports.updateRedeem = function updateRedeem (session, cb) { var sql = 'UPDATE transactions SET redeem=$1 ' + 'WHERE incoming=$2 AND device_fingerprint=$3 AND session_id=$4 ' + diff --git a/migrations/008-add-two-way.js b/migrations/008-add-two-way.js index 4f9a00d6..5051e897 100644 --- a/migrations/008-add-two-way.js +++ b/migrations/008-add-two-way.js @@ -12,6 +12,7 @@ exports.up = function (next) { 'alter table transactions add dispensed boolean NOT NULL DEFAULT false', 'alter table transactions add notified boolean NOT NULL DEFAULT false', 'alter table transactions add redeem boolean NOT NULL DEFAULT false', + 'alter table transactions add confirmation_time timestamp', 'alter table transactions add status status_stage NOT NULL DEFAULT \'notSeen\'' ] db.multi(sql, next)