add more db fields for fixed fee

This commit is contained in:
Josh Harvey 2017-05-19 01:34:09 +03:00
parent 8ecc8ce510
commit 8cdad0bc15
10 changed files with 74 additions and 65 deletions

View file

@ -45,7 +45,7 @@
"cashInCommission", "cashInCommission",
"cashOutCommission", "cashOutCommission",
"cashInFee", "cashInFee",
"cashOutFee" "minimumTx"
] ]
}, },
{ {
@ -131,9 +131,9 @@
}, },
{ {
"code": "cashInFee", "code": "cashInFee",
"displayTop": "Fixed Fees", "displayTop": "Cash-in",
"displayBottom": "Fixed Fee",
"displayTopCount": 2, "displayTopCount": 2,
"displayBottom": "Cash-in",
"fieldType": "integer", "fieldType": "integer",
"fieldClass": "fiat", "fieldClass": "fiat",
"cryptoScope": "both", "cryptoScope": "both",
@ -150,8 +150,8 @@
] ]
}, },
{ {
"code": "cashOutFee", "code": "minimumTx",
"displayBottom": "Cash-out", "displayBottom": "Minimum Tx",
"displayTopCount": 0, "displayTopCount": 0,
"fieldType": "integer", "fieldType": "integer",
"fieldClass": "fiat", "fieldClass": "fiat",
@ -159,7 +159,6 @@
"machineScope": "both", "machineScope": "both",
"default": 0, "default": 0,
"enabledIf": [ "enabledIf": [
"cashOutEnabled"
], ],
"fieldValidation": [ "fieldValidation": [
{ {

View file

@ -3,4 +3,8 @@ const BigNumber = require('bignumber.js')
BigNumber.config({ROUNDING_MODE: BigNumber.ROUND_HALF_EVEN}) BigNumber.config({ROUNDING_MODE: BigNumber.ROUND_HALF_EVEN})
function BN (s, radix) { return new BigNumber(s, radix) } function BN (s, radix) { return new BigNumber(s, radix) }
BN.min = BigNumber.min
BN.max = BigNumber.max
module.exports = BN module.exports = BN

View file

@ -5,8 +5,6 @@ const BN = require('./bn')
const plugins = require('./plugins') const plugins = require('./plugins')
const logger = require('./logger') const logger = require('./logger')
const mapValuesWithKey = _.mapValues.convert({cap: false})
module.exports = {post, monitorPending} module.exports = {post, monitorPending}
const PENDING_INTERVAL = '1 day' const PENDING_INTERVAL = '1 day'
@ -84,12 +82,10 @@ function ensureRatchet (oldField, newField, fieldKey) {
return true return true
} }
if (oldField.isBigNumber && newField.isBigNumber) return BN(oldField).eq(newField)
if (oldField.toString() === newField.toString()) return true if (oldField.toString() === newField.toString()) return true
logger.error('This field [%s] should never change', fieldKey) return false
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) {
@ -108,7 +104,7 @@ function diff (oldTx, newTx) {
logger.warn('Value from lamassu-machine would violate ratchet [%s]', fieldKey) logger.warn('Value from lamassu-machine would violate ratchet [%s]', fieldKey)
logger.warn('Old tx: %j', oldTx) logger.warn('Old tx: %j', oldTx)
logger.warn('New tx: %j', newTx) logger.warn('New tx: %j', newTx)
return throw new Error('Value from lamassu-machine would violate ratchet')
} }
updatedTx[fieldKey] = newField updatedTx[fieldKey] = newField
@ -125,7 +121,7 @@ function toObj (row) {
keys.forEach(key => { keys.forEach(key => {
const objKey = _.camelCase(key) const objKey = _.camelCase(key)
if (key === 'crypto_atoms' || key === 'fiat') { if (key === 'crypto_atoms' || key === 'fiat' || key === 'cash_in_fee') {
newObj[objKey] = BN(row[key]) newObj[objKey] = BN(row[key])
return return
} }
@ -144,15 +140,11 @@ function toObj (row) {
} }
function convertBigNumFields (obj) { function convertBigNumFields (obj) {
const convert = (value, key) => _.includes(key, ['cryptoAtoms', 'fiat']) const convert = value => value && value.isBigNumber
? value.toString() ? value.toString()
: value : value
const convertKey = key => _.includes(key, ['cryptoAtoms', 'fiat']) return _.mapValues(convert, obj)
? key + '#'
: key
return _.mapKeys(convertKey, mapValuesWithKey(convert, obj))
} }
function pullNewBills (billRows, machineTx) { function pullNewBills (billRows, machineTx) {

View file

@ -2,6 +2,7 @@ const _ = require('lodash/fp')
const db = require('./db') const db = require('./db')
const configManager = require('./config-manager') const configManager = require('./config-manager')
const logger = require('./logger')
const schema = require('../lamassu-schema.json') const schema = require('../lamassu-schema.json')
function allScopes (cryptoScopes, machineScopes) { function allScopes (cryptoScopes, machineScopes) {
@ -122,7 +123,10 @@ function ensureConstraints (config) {
config.every(fieldInstance => { config.every(fieldInstance => {
const fieldCode = fieldInstance.fieldLocator.code const fieldCode = fieldInstance.fieldLocator.code
const field = pickField(fieldCode) const field = pickField(fieldCode)
if (!field) throw new Error('No such field: ' + fieldCode) if (!field) {
logger.error('No such field: %s, %j', fieldCode, fieldInstance.fieldLocator.fieldScope)
throw new Error('No such field: ' + fieldCode)
}
const fieldValue = fieldInstance.fieldValue const fieldValue = fieldInstance.fieldValue

View file

@ -165,6 +165,19 @@ function plugins (settings, deviceId) {
.then(row => row.id) .then(row => row.id)
} }
function mapCoinSettings (coin) {
const config = configManager.scoped(coin, deviceId, settings.config)
const minimumTx = BN(config.minimumTx)
const cashInFee = BN(config.cashInFee)
const coinSettings = {
minimumTx: BN.max(minimumTx, cashInFee),
cashInFee: cashInFee
}
return [coin, coinSettings]
}
function pollQueries (serialNumber, deviceTime, deviceRec) { function pollQueries (serialNumber, deviceTime, deviceRec) {
const config = configManager.machineScoped(deviceId, settings.config) const config = configManager.machineScoped(deviceId, settings.config)
const fiatCode = config.fiatCurrency const fiatCode = config.fiatCurrency
@ -184,7 +197,7 @@ function plugins (settings, deviceId) {
return Promise.all(promises) return Promise.all(promises)
.then(arr => { .then(arr => {
const cassettes = arr[0] const cassettes = arr[0]
const currentConfigVersion = arr[2] const configVersion = arr[2]
const tickers = arr.slice(3, cryptoCodes.length + 3) const tickers = arr.slice(3, cryptoCodes.length + 3)
const balances = arr.slice(cryptoCodes.length + 3) const balances = arr.slice(cryptoCodes.length + 3)
@ -192,7 +205,8 @@ function plugins (settings, deviceId) {
cassettes, cassettes,
rates: buildRates(tickers), rates: buildRates(tickers),
balances: buildBalances(balances), balances: buildBalances(balances),
currentConfigVersion coinSettings: _.fromPairs(_.map(mapCoinSettings, cryptoCodes)),
configVersion
} }
}) })
} }

View file

@ -63,18 +63,14 @@ function poll (req, res, next) {
twoWayMode: config.cashOutEnabled, twoWayMode: config.cashOutEnabled,
zeroConfLimit: config.zeroConfLimit, zeroConfLimit: config.zeroConfLimit,
fiatTxLimit: config.cashOutTransactionLimit, fiatTxLimit: config.cashOutTransactionLimit,
reboot, reboot
rates: results.rates,
balances: results.balances,
coins: config.cryptoCurrencies,
configVersion: results.currentConfigVersion
} }
if (response.idVerificationEnabled) { if (response.idVerificationEnabled) {
response.idVerificationLimit = config.idVerificationLimit response.idVerificationLimit = config.idVerificationLimit
} }
return res.json(response) return res.json(_.assign(response, results))
}) })
.catch(next) .catch(next)
} }

View file

@ -131,9 +131,12 @@ function settings () {
return settingsCache return settingsCache
} }
const pp = require('./pp')
function save (config) { function save (config) {
const sql = 'insert into user_config (type, data, valid) values ($1, $2, $3)' const sql = 'insert into user_config (type, data, valid) values ($1, $2, $3)'
console.log(pp('DEBUG101')(config))
return configValidate.validate(config) return configValidate.validate(config)
.then(() => db.none(sql, ['config', {config}, true])) .then(() => db.none(sql, ['config', {config}, true]))
.catch(() => db.none(sql, ['config', {config}, false])) .catch(() => db.none(sql, ['config', {config}, false]))

View file

@ -21,7 +21,15 @@ function massage (tx) {
const transformDate = (v, k) => isDateField(k) ? new Date(v) : v const transformDate = (v, k) => isDateField(k) ? new Date(v) : v
const mapValuesWithKey = _.mapValues.convert({'cap': false}) const mapValuesWithKey = _.mapValues.convert({'cap': false})
const transformDates = r => mapValuesWithKey(transformDate, r) const transformDates = r => mapValuesWithKey(transformDate, r)
const mapBN = r => _.assign(r, {cryptoAtoms: BN(r.cryptoAtoms), fiat: BN(r.fiat)})
const mapBN = r => {
const update = r.direction === 'cashIn'
? {cryptoAtoms: BN(r.cryptoAtoms), fiat: BN(r.fiat), cashInFee: BN(r.cashInFee)}
: {cryptoAtoms: BN(r.cryptoAtoms), fiat: BN(r.fiat)}
return _.assign(r, update)
}
const mapper = _.flow(transformDates, mapBN, _.unset('dirty')) const mapper = _.flow(transformDates, mapBN, _.unset('dirty'))
return mapper(tx) return mapper(tx)

View file

@ -0,0 +1,17 @@
var db = require('./db')
exports.up = function (next) {
var sql = [
'alter table cash_in_txs add column cash_in_fee numeric(14, 5) not null',
'alter table cash_in_txs add column cash_in_fee_crypto bigint not null',
'alter table cash_in_txs add column minimum_tx integer not null',
'alter table bills add column cash_in_fee numeric(14, 5) not null',
'alter table bills add column cash_in_fee_crypto bigint not null',
'alter table bills add column crypto_atoms_after_fee bigint not null'
]
db.multi(sql, next)
}
exports.down = function (next) {
next()
}

View file

@ -1,40 +1,12 @@
'use strict' const settingsLoader = require('../lib/settings-loader')
const R = require('ramda') const fields = [
const db = require('../db') settingsLoader.configDeleteField({crypto: 'global', machine: 'global'}, 'cashOutFee'),
settingsLoader.configDeleteField({crypto: 'global', machine: 'global'}, 'minTx')
]
function pp (o) { settingsLoader.modifyConfig(fields)
console.log(require('util').inspect(o, {depth: null, colors: true}))
}
function dbFetchConfig () {
return db.oneOrNone('select data from user_config where type=$1', ['config'])
.then(row => row && row.data)
}
dbFetchConfig()
.then(c => {
const groups = c.groups
.filter(g => g.code !== 'fiat')
.map(g => {
if (g.code === 'currencies') {
const values = g.values.filter(v => v.fieldLocator.code !== 'cryptoCurrencies')
return R.assoc('values', values, g)
}
return g
})
return {groups: groups}
})
.then(config => {
pp(config)
return db.none('update user_config set data=$1 where type=$2', [config, 'config'])
})
.then(() => { .then(() => {
console.log('success.')
process.exit(0) process.exit(0)
}) })
.catch(e => {
console.log(e)
process.exit(1)
})