WIP
This commit is contained in:
parent
b62cd590ef
commit
5312086622
3 changed files with 127 additions and 131 deletions
|
|
@ -243,9 +243,7 @@ exports.getConfig = function getConfig () {
|
|||
return cachedConfig
|
||||
}
|
||||
|
||||
exports.logEvent = function event (session, rawEvent) {
|
||||
return db.recordDeviceEvent(session, rawEvent)
|
||||
}
|
||||
exports.logEvent = db.recordDeviceEvent
|
||||
|
||||
function buildCartridges (cartridges, virtualCartridges, rec) {
|
||||
return {
|
||||
|
|
@ -264,12 +262,12 @@ function buildCartridges (cartridges, virtualCartridges, rec) {
|
|||
}
|
||||
}
|
||||
|
||||
exports.pollQueries = function pollQueries (session) {
|
||||
exports.pollQueries = function pollQueries (deviceId) {
|
||||
const cartridges = cachedConfig.exchanges.settings.cartridges
|
||||
if (!cartridges) return Promise.resolve({})
|
||||
const virtualCartridges = cachedConfig.exchanges.settings.virtualCartridges
|
||||
|
||||
return db.cartridgeCounts(session)
|
||||
return db.cartridgeCounts(deviceId)
|
||||
.then(result => ({
|
||||
cartridges: buildCartridges(cartridges, virtualCartridges, result)
|
||||
}))
|
||||
|
|
@ -298,8 +296,8 @@ function _sendCoinsCb (toAddress, cryptoAtoms, cryptoCode, cb) {
|
|||
|
||||
// NOTE: This will fail if we have already sent coins because there will be
|
||||
// a db unique db record in the table already.
|
||||
function executeTx (fingerprint, tx) {
|
||||
return db.addOutgoingTx(fingerprint, tx)
|
||||
function executeTx (deviceId, tx) {
|
||||
return db.addOutgoingTx(deviceId, tx)
|
||||
.then(() => _sendCoins(tx.toAddress, tx.cryptoAtoms, tx.cryptoCode))
|
||||
.then(txHash => {
|
||||
const fee = null // Need to fill this out in plugins
|
||||
|
|
@ -316,7 +314,7 @@ function executeTx (fingerprint, tx) {
|
|||
}
|
||||
|
||||
// TODO: Run these in parallel and return success
|
||||
exports.trade = function trade (session, rawTrade) {
|
||||
exports.trade = function trade (deviceId, rawTrade) {
|
||||
// TODO: move this to DB, too
|
||||
// add bill to trader queue (if trader is enabled)
|
||||
const cryptoCode = rawTrade.cryptoCode || 'BTC'
|
||||
|
|
@ -332,41 +330,41 @@ exports.trade = function trade (session, rawTrade) {
|
|||
})
|
||||
}
|
||||
|
||||
return db.recordBill(session, rawTrade)
|
||||
return db.recordBill(deviceId, rawTrade)
|
||||
}
|
||||
|
||||
exports.stateChange = function stateChange (session, rec, cb) {
|
||||
exports.stateChange = function stateChange (deviceId, deviceTime, rec, cb) {
|
||||
const event = {
|
||||
id: rec.uuid,
|
||||
fingerprint: session.fingerprint,
|
||||
fingerprint: deviceId,
|
||||
eventType: 'stateChange',
|
||||
note: JSON.stringify({state: rec.state, isIdle: rec.isIdle, sessionId: session.id}),
|
||||
deviceTime: session.deviceTime
|
||||
note: JSON.stringify({state: rec.state, isIdle: rec.isIdle, txId: rec.txId}),
|
||||
deviceTime: deviceTime
|
||||
}
|
||||
return db.machineEvent(event)
|
||||
}
|
||||
|
||||
exports.recordPing = function recordPing (session, rec, cb) {
|
||||
exports.recordPing = function recordPing (deviceId, deviceTime, rec, cb) {
|
||||
const event = {
|
||||
id: uuid.v4(),
|
||||
fingerprint: session.fingerprint,
|
||||
fingerprint: deviceId,
|
||||
eventType: 'ping',
|
||||
note: JSON.stringify({state: rec.state, isIdle: rec.idle === 'true', sessionId: session.id}),
|
||||
deviceTime: session.deviceTime
|
||||
note: JSON.stringify({state: rec.state, isIdle: rec.idle === 'true', txId: rec.txId}),
|
||||
deviceTime: deviceTime
|
||||
}
|
||||
return db.machineEvent(event)
|
||||
}
|
||||
|
||||
exports.sendCoins = function sendCoins (session, rawTx) {
|
||||
return executeTx(session.fingerprint, rawTx)
|
||||
exports.sendCoins = function sendCoins (rawTx) {
|
||||
return executeTx(rawTx)
|
||||
}
|
||||
|
||||
exports.cashOut = function cashOut (session, tx) {
|
||||
exports.cashOut = function cashOut (tx) {
|
||||
const cryptoCode = tx.cryptoCode || 'BTC'
|
||||
const walletPlugin = walletPlugins[cryptoCode]
|
||||
|
||||
const serialPromise = walletPlugin.supportsHD
|
||||
? db.nextCashOutSerialHD(tx.sessionId, cryptoCode)
|
||||
? db.nextCashOutSerialHD(tx.id, cryptoCode)
|
||||
: Promise.resolve()
|
||||
|
||||
return serialPromise
|
||||
|
|
@ -381,15 +379,13 @@ exports.cashOut = function cashOut (session, tx) {
|
|||
if (err) return reject(err)
|
||||
|
||||
const newTx = R.assoc('toAddress', address, tx)
|
||||
return db.addInitialIncoming(session, newTx, address)
|
||||
return db.addInitialIncoming(newTx, address)
|
||||
.then(() => resolve(address))
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
exports.dispenseAck = function dispenseAck (session, rec) {
|
||||
return db.addDispense(session, rec.tx, rec.cartridges)
|
||||
}
|
||||
exports.dispenseAck = db.addDispense
|
||||
|
||||
exports.fiatBalance = function fiatBalance (cryptoCode) {
|
||||
const deviceRate = exports.getDeviceRate(cryptoCode)
|
||||
|
|
@ -765,13 +761,8 @@ exports.getPhoneCode = function getPhoneCode (phone) {
|
|||
.then(() => code)
|
||||
}
|
||||
|
||||
exports.updatePhone = function updatePhone (session, tx, notified) {
|
||||
return db.addIncomingPhone(session, tx, notified)
|
||||
}
|
||||
|
||||
exports.registerRedeem = function registerRedeem (session) {
|
||||
return db.updateRedeem(session)
|
||||
}
|
||||
exports.updatePhone = db.addIncomingPhone
|
||||
exports.registerRedeem = db.updateRedeem
|
||||
|
||||
exports.fetchPhoneTx = function fetchPhoneTx (phone) {
|
||||
return db.fetchPhoneTxs(phone, TRANSACTION_EXPIRATION)
|
||||
|
|
@ -798,9 +789,9 @@ exports.requestDispense = function requestDispense (tx) {
|
|||
return db.addDispenseRequest(tx)
|
||||
}
|
||||
|
||||
exports.cachedResponse = (session, path, method) => db.cachedResponse(session, path, method)
|
||||
exports.cachedResponse = db.cachedResponse
|
||||
|
||||
exports.cacheResponse = (session, path, method, body) => db.cacheResponse(session, path, method, body)
|
||||
exports.cacheResponse = db.cacheResponse
|
||||
|
||||
function sweepHD (row) {
|
||||
const cryptoCode = row.crypto_code
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ exports.init = function init (conString) {
|
|||
}
|
||||
|
||||
// logs inputted bill and overall tx status (if available)
|
||||
exports.recordBill = function recordBill (session, rec) {
|
||||
exports.recordBill = function recordBill (deviceId, rec) {
|
||||
const fields = [
|
||||
'id',
|
||||
'device_fingerprint',
|
||||
'currency_code',
|
||||
'crypto_code',
|
||||
'to_address',
|
||||
'session_id',
|
||||
'tx_id',
|
||||
'device_time',
|
||||
'satoshis',
|
||||
'denomination'
|
||||
|
|
@ -56,11 +56,11 @@ exports.recordBill = function recordBill (session, rec) {
|
|||
|
||||
const values = [
|
||||
rec.uuid,
|
||||
session.fingerprint,
|
||||
deviceId,
|
||||
rec.currency,
|
||||
rec.cryptoCode,
|
||||
rec.toAddress,
|
||||
session.id,
|
||||
rec.txId,
|
||||
rec.deviceTime,
|
||||
rec.cryptoAtoms.toString(),
|
||||
rec.fiat
|
||||
|
|
@ -73,10 +73,10 @@ exports.recordBill = function recordBill (session, rec) {
|
|||
})
|
||||
}
|
||||
|
||||
exports.recordDeviceEvent = function recordDeviceEvent (session, event) {
|
||||
const sql = 'INSERT INTO device_events (device_fingerprint, event_type, ' +
|
||||
exports.recordDeviceEvent = function recordDeviceEvent (deviceId, event) {
|
||||
const sql = 'INSERT INTO device_events (device_id, event_type, ' +
|
||||
'note, device_time) VALUES ($1, $2, $3, $4)'
|
||||
const values = [session.fingerprint, event.eventType, event.note,
|
||||
const values = [deviceId, event.eventType, event.note,
|
||||
event.deviceTime]
|
||||
return db.none(sql, values)
|
||||
}
|
||||
|
|
@ -158,11 +158,11 @@ function insertDispense (session, tx, cartridges) {
|
|||
return db.none(sql, values)
|
||||
}
|
||||
|
||||
exports.addIncomingPhone = function addIncomingPhone (session, tx, notified) {
|
||||
exports.addIncomingPhone = function addIncomingPhone (tx, notified) {
|
||||
const sql = `UPDATE cash_out_txs SET phone=$1, notified=$2
|
||||
WHERE session_id=$3
|
||||
WHERE tx_id=$3
|
||||
AND phone IS NULL`
|
||||
const values = [tx.phone, notified, tx.sessionId]
|
||||
const values = [tx.phone, notified, tx.id]
|
||||
|
||||
return db.result(sql, values)
|
||||
.then(results => {
|
||||
|
|
@ -171,7 +171,7 @@ exports.addIncomingPhone = function addIncomingPhone (session, tx, notified) {
|
|||
|
||||
if (noPhone) return {noPhone: noPhone}
|
||||
|
||||
return db.none(sql2, [tx.sessionId, 'addedPhone'])
|
||||
return db.none(sql2, [tx.txId, 'addedPhone'])
|
||||
.then(() => ({noPhone: noPhone}))
|
||||
})
|
||||
}
|
||||
|
|
@ -244,11 +244,11 @@ exports.addDispense = function addDispense (session, tx, cartridges) {
|
|||
})
|
||||
}
|
||||
|
||||
exports.cartridgeCounts = function cartridgeCounts (session) {
|
||||
exports.cartridgeCounts = function cartridgeCounts (deviceId) {
|
||||
const sql = 'SELECT id, count1, count2 FROM dispenses ' +
|
||||
'WHERE device_fingerprint=$1 AND refill=$2 ' +
|
||||
'ORDER BY id DESC LIMIT 1'
|
||||
return db.oneOrNone(sql, [session.fingerprint, true])
|
||||
return db.oneOrNone(sql, [deviceId, true])
|
||||
.then(row => {
|
||||
const counts = row ? [row.count1, row.count2] : [0, 0]
|
||||
return {id: row.id, counts: counts}
|
||||
|
|
@ -360,14 +360,14 @@ exports.updateTxStatus = function updateTxStatus (tx, status) {
|
|||
})
|
||||
}
|
||||
|
||||
exports.updateRedeem = function updateRedeem (session) {
|
||||
const sql = 'UPDATE cash_out_txs SET redeem=$1 WHERE session_id=$2'
|
||||
const values = [true, session.id]
|
||||
exports.updateRedeem = function updateRedeem (txId) {
|
||||
const sql = 'UPDATE cash_out_txs SET redeem=$1 WHERE txId=$2'
|
||||
const values = [true, txId]
|
||||
|
||||
return db.none(sql, values)
|
||||
.then(() => {
|
||||
const sql2 = 'insert into cash_out_actions (session_id, action) values ($1, $2)'
|
||||
return db.none(sql2, [session.id, 'redeem'])
|
||||
return db.none(sql2, [txId, 'redeem'])
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -382,29 +382,29 @@ exports.updateNotify = function updateNotify (tx) {
|
|||
})
|
||||
}
|
||||
|
||||
function insertCachedRequest (session, path, method, body) {
|
||||
function insertCachedRequest (deviceId, txId, path, method, body) {
|
||||
const fields = [
|
||||
'device_fingerprint',
|
||||
'session_id',
|
||||
'device_id',
|
||||
'tx_id',
|
||||
'path',
|
||||
'method',
|
||||
'body'
|
||||
]
|
||||
|
||||
const sql = getInsertQuery('cached_responses', fields)
|
||||
return db.none(sql, [session.fingerprint, session.id, path, method, body])
|
||||
return db.none(sql, [deviceId, txId, path, method, body])
|
||||
}
|
||||
|
||||
exports.cachedResponse = function (session, path, method) {
|
||||
exports.cachedResponse = function (deviceId, txId, path, method) {
|
||||
const sql = `select body from cached_responses
|
||||
where device_fingerprint=$1
|
||||
and session_id=$2
|
||||
where device_id=$1
|
||||
and tx_id=$2
|
||||
and path=$3
|
||||
and method=$4`
|
||||
|
||||
const values = [session.fingerprint, session.id, path, method]
|
||||
const values = [deviceId, txId, path, method]
|
||||
|
||||
return insertCachedRequest(session, path, method, {pendingRequest: true})
|
||||
return insertCachedRequest(deviceId, txId, path, method, {pendingRequest: true})
|
||||
.then(() => ({}))
|
||||
.catch(err => {
|
||||
if (!isUniqueViolation(err)) throw err
|
||||
|
|
@ -422,15 +422,15 @@ function pruneCachedResponses () {
|
|||
return db.none(sql, values)
|
||||
}
|
||||
|
||||
exports.cacheResponse = function (session, path, method, body) {
|
||||
exports.cacheResponse = function (deviceId, txId, path, method, body) {
|
||||
const sql = `update cached_responses
|
||||
set body=$1
|
||||
where device_fingerprint=$2
|
||||
and session_id=$3
|
||||
where device_id=$2
|
||||
and tx_id=$3
|
||||
and path=$4
|
||||
and method=$5`
|
||||
|
||||
const values = [body, session.fingerprint, session.id, path, method]
|
||||
const values = [body, deviceId, txId, path, method]
|
||||
|
||||
return db.none(sql, values)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ let lamassuConfig
|
|||
|
||||
module.exports = {
|
||||
init,
|
||||
getFingerprint
|
||||
getDeviceId
|
||||
}
|
||||
|
||||
const STALE_TICKER = 3 * 60 * 1000
|
||||
|
|
@ -57,12 +57,13 @@ function buildBalances () {
|
|||
}
|
||||
|
||||
function poll (req, res) {
|
||||
const fingerprint = getFingerprint(req)
|
||||
const deviceId = getDeviceId(req)
|
||||
const deviceTime = getDeviceTime(req)
|
||||
const pid = req.query.pid
|
||||
|
||||
pids[fingerprint] = {pid, ts: Date.now()}
|
||||
pids[deviceId] = {pid, ts: Date.now()}
|
||||
|
||||
logger.debug('poll request from: %s', fingerprint)
|
||||
logger.debug('poll request from: %s', deviceId)
|
||||
|
||||
let rates = {}
|
||||
let balances = {}
|
||||
|
|
@ -74,11 +75,11 @@ function poll (req, res) {
|
|||
const settings = config.exchanges.settings
|
||||
const complianceSettings = settings.compliance
|
||||
|
||||
plugins.pollQueries(session(req))
|
||||
plugins.pollQueries(deviceId)
|
||||
.then(results => {
|
||||
const cartridges = results.cartridges
|
||||
|
||||
const reboot = reboots[fingerprint] === pid
|
||||
const reboot = reboots[deviceId] === pid
|
||||
|
||||
const response = {
|
||||
err: null,
|
||||
|
|
@ -103,7 +104,7 @@ function poll (req, res) {
|
|||
})
|
||||
.catch(logger.error)
|
||||
|
||||
plugins.recordPing(session(req), req.query)
|
||||
plugins.recordPing(deviceId, deviceTime, req.query)
|
||||
.catch(logger.error)
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ function trade (req, res) {
|
|||
const tx = req.body
|
||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||
|
||||
plugins.trade(session(req), tx)
|
||||
plugins.trade(getDeviceId(req), tx)
|
||||
.then(() => res.status(201).json({}))
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
|
|
@ -120,7 +121,7 @@ function trade (req, res) {
|
|||
}
|
||||
|
||||
function stateChange (req, res) {
|
||||
plugins.stateChange(session(req), req.body)
|
||||
plugins.stateChange(getDeviceId(req), getDeviceTime(req), req.body)
|
||||
.then(() => res.json({success: true}))
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
|
|
@ -135,7 +136,7 @@ function send (req, res) {
|
|||
// TODO: use status.statusCode here after confirming machine compatibility
|
||||
// FIX: (joshm) set txHash to status.txId instead of previous status.txHash which wasn't being set
|
||||
// Need to clean up txHash vs txId
|
||||
return plugins.sendCoins(session(req), tx)
|
||||
return plugins.sendCoins(getDeviceId(req), tx)
|
||||
.then(status => res.json({
|
||||
txHash: status && status.txHash,
|
||||
txId: status && status.txId
|
||||
|
|
@ -154,8 +155,8 @@ function cashOut (req, res) {
|
|||
const tx = req.body
|
||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||
|
||||
return plugins.cashOut(session(req), req.body)
|
||||
.then(cryptoAddress => res.json({bitcoinAddress: cryptoAddress}))
|
||||
return plugins.cashOut(tx)
|
||||
.then(cryptoAddress => res.json({toAddress: cryptoAddress}))
|
||||
.catch(err => {
|
||||
res.json({
|
||||
err: err.message,
|
||||
|
|
@ -166,12 +167,12 @@ function cashOut (req, res) {
|
|||
}
|
||||
|
||||
function dispenseAck (req, res) {
|
||||
plugins.dispenseAck(session(req), req.body)
|
||||
plugins.dispenseAck(req.body)
|
||||
res.json({success: true})
|
||||
}
|
||||
|
||||
function deviceEvent (req, res) {
|
||||
plugins.logEvent(session(req), req.body)
|
||||
plugins.logEvent(getDeviceId(req), req.body)
|
||||
res.json({err: null})
|
||||
}
|
||||
|
||||
|
|
@ -207,7 +208,7 @@ function pair (req, res) {
|
|||
|
||||
lamassuConfig.pair(
|
||||
token,
|
||||
getFingerprint(req),
|
||||
getDeviceId(req),
|
||||
name,
|
||||
err => {
|
||||
if (err) {
|
||||
|
|
@ -235,7 +236,9 @@ function phoneCode (req, res) {
|
|||
|
||||
function updatePhone (req, res) {
|
||||
const notified = req.query.notified === 'true'
|
||||
return plugins.updatePhone(session(req), req.body, notified)
|
||||
const tx = req.body
|
||||
|
||||
return plugins.updatePhone(tx, notified)
|
||||
.then(r => res.json(r))
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
|
|
@ -253,7 +256,8 @@ function fetchPhoneTx (req, res) {
|
|||
}
|
||||
|
||||
function registerRedeem (req, res) {
|
||||
return plugins.registerRedeem(session(req))
|
||||
const txId = req.params.txId
|
||||
return plugins.registerRedeem(txId)
|
||||
.then(() => res.json({success: true}))
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
|
|
@ -263,7 +267,7 @@ function registerRedeem (req, res) {
|
|||
|
||||
function waitForDispense (req, res) {
|
||||
logger.debug('waitForDispense')
|
||||
return plugins.fetchTx(session(req))
|
||||
return plugins.fetchTx(req.params.txId)
|
||||
.then(tx => {
|
||||
logger.debug('tx fetched')
|
||||
logger.debug(tx)
|
||||
|
|
@ -279,7 +283,15 @@ function waitForDispense (req, res) {
|
|||
|
||||
function dispense (req, res) {
|
||||
const tx = req.body.tx
|
||||
const deviceId = getDeviceId(req)
|
||||
|
||||
return cachedResponse(deviceId, tx.id, req)
|
||||
.then(r => {
|
||||
// Cache hit
|
||||
if (r.body && r.body.pendingRequest) return res.sendStatus(409)
|
||||
if (r.body) res.json(r.body)
|
||||
|
||||
// No cache hit
|
||||
return plugins.requestDispense(tx)
|
||||
.then(r => {
|
||||
return cacheResponse(req, r)
|
||||
|
|
@ -289,6 +301,7 @@ function dispense (req, res) {
|
|||
logger.error(err)
|
||||
res.sendStatus(500)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function init (localConfig) {
|
||||
|
|
@ -316,9 +329,9 @@ function init (localConfig) {
|
|||
app.post('/phone_code', authMiddleware, phoneCode)
|
||||
app.post('/update_phone', authMiddleware, updatePhone)
|
||||
app.get('/phone_tx', authMiddleware, fetchPhoneTx)
|
||||
app.post('/register_redeem', authMiddleware, registerRedeem)
|
||||
app.get('/await_dispense', authMiddleware, waitForDispense)
|
||||
app.post('/dispense', authMiddleware, cachedResponse, dispense)
|
||||
app.post('/register_redeem/:txId', authMiddleware, registerRedeem)
|
||||
app.get('/await_dispense/:txId', authMiddleware, waitForDispense)
|
||||
app.post('/dispense', authMiddleware, dispense)
|
||||
|
||||
localApp.get('/pid', (req, res) => {
|
||||
const machineFingerprint = req.query.fingerprint
|
||||
|
|
@ -342,28 +355,20 @@ function init (localConfig) {
|
|||
return app
|
||||
}
|
||||
|
||||
function session (req) {
|
||||
return {
|
||||
fingerprint: getFingerprint(req),
|
||||
id: req.get('session-id'),
|
||||
deviceTime: Date.parse(req.get('date'))
|
||||
}
|
||||
function getDeviceTime (req) {
|
||||
return Date.parse(req.get('date'))
|
||||
}
|
||||
|
||||
function getFingerprint (req) {
|
||||
function getDeviceId (req) {
|
||||
return (typeof req.connection.getPeerCertificate === 'function' &&
|
||||
req.connection.getPeerCertificate().fingerprint) || 'unknown'
|
||||
}
|
||||
|
||||
function cachedResponse (req, res, next) {
|
||||
return plugins.cachedResponse(session(req), req.path, req.method)
|
||||
.then(r => {
|
||||
if (!r.body) return next()
|
||||
if (r.body.pendingRequest) return res.sendStatus(409)
|
||||
res.json(r.body)
|
||||
})
|
||||
function cachedResponse (deviceId, txId, req) {
|
||||
return plugins.cachedResponse(deviceId, txId, req.path, req.method)
|
||||
.then(r => r.body)
|
||||
}
|
||||
|
||||
function cacheResponse (req, body) {
|
||||
return plugins.cacheResponse(session(req), req.path, req.method, body)
|
||||
function cacheResponse (deviceId, txId, req, body) {
|
||||
return plugins.cacheResponse(deviceId, txId, req.path, req.method, body)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue