WIP migrations

This commit is contained in:
Josh Harvey 2014-11-20 00:40:27 -05:00
parent e650e591d5
commit 7a2ab111d6
3 changed files with 38 additions and 107 deletions

View file

@ -7,9 +7,6 @@ var SATOSHI_FACTOR = 1e8;
var POLLING_RATE = 60 * 1000; // poll each minute
var REAP_RATE = 5 * 1000;
var PENDING_TIMEOUT = 70 * 1000;
var RECOMMENDED_FEE = 10000;
var TX_0CONF_WAIT_TIME = 20 * 1000; // wait 20 seconds
var MIN_CONFIDENCE = 0.7;
var db = null;
@ -215,16 +212,29 @@ function executeTx(deviceFingerprint, tx, cb) {
});
}
function reapIncomingTx(deviceFingerprint, tx) {
executeTx(deviceFingerprint, tx, function(err) {
if (err) logger.error(err);
});
}
function reapOutgoingTx(deviceFingerprint, tx) {
infoPlugin.checkAddress(tx.toAddress, function(err, status, satoshisReceived) {
if (status === 'notSeen') return;
db.addOutgoingTx(deviceFingerprint, tx, status, satoshisReceived);
});
}
function reapTx(row) {
var deviceFingerprint = row.device_fingerprint;
var tx = {
txId: row.txid,
toAddress: row.to_address,
currencyCode: row.currency_code
currencyCode: row.currency_code,
incoming: row.incoming
};
executeTx(deviceFingerprint, tx, function(err) {
if (err) logger.error(err);
});
if (row.incoming) reapIncomingTx(deviceFingerprint, tx);
else reapOutgoingTx(deviceFingerprint, tx);
}
function reapTxs() {
@ -253,6 +263,8 @@ exports.trade = function trade(deviceFingerprint, rawTrade, cb) {
var tx = {
txId: rawTrade.txId,
fiat: 0,
satoshis: 0,
toAddress: rawTrade.toAddress,
currencyCode: rawTrade.currency
};
@ -297,82 +309,6 @@ function _setDispenseStatus(deviceFingerprint, tx, status, deposit) {
dispenseStatuses[deviceFingerprint] = statusObject;
}
function _checkTx(deviceFingerprint, tx, txInfo) {
// accept if tx is already confirmed
if (txInfo.confirmations > 0) {
_setDispenseStatus(deviceFingerprint, tx, 'authorizedDeposit', txInfo.amount);
return true;
}
// NOTE: we can put some heuristics here
// consider authorization raported by the 'info' plugin
if (txInfo.authorized === true && txInfo.confidence >= MIN_CONFIDENCE) {
_setDispenseStatus(deviceFingerprint, tx, 'authorizedDeposit', txInfo.amount);
return true;
}
// SHOULD TAKE MUCH MORE FACTORS INTO ACCOUNT HERE
// accept txs with recommended fee and with at least 20s of propagation time
if (txInfo.fees >= RECOMMENDED_FEE && txInfo.tsReceived + TX_0CONF_WAIT_TIME < Date.now()) {
_setDispenseStatus(deviceFingerprint, tx, 'authorizedDeposit', txInfo.amount);
return true;
}
return false;
}
// this is invoked only when tx is fresh enough AND is for a right amount
function _monitorTx(deviceFingerprint, tx) {
infoPlugin.getTx(tx.txHash, tx.toAddress, function(err, txInfo) {
if (err) {
logger.error(err);
return setTimeout(_monitorTx, 300, deviceFingerprint, tx);
}
if (_checkTx(deviceFingerprint, tx, txInfo))
return;
setTimeout(_monitorTx, 300, deviceFingerprint, tx);
});
}
function _monitorAddress(deviceFingerprint, tx) {
if (!tx) throw new Error('No tx');
infoPlugin.getAddressLastTx(tx.toAddress, function(err, txInfo) {
if (err) {
logger.error(err);
return setTimeout(_monitorAddress, 300, deviceFingerprint, tx);
}
// no tx occured at all or deposit address was reused; some previous tx was returned
if (!txInfo || txInfo.tsReceived < tx.created) {
return setTimeout(_monitorAddress, 300, deviceFingerprint, tx);
}
// when sent TX is not enough
if (txInfo.amount < tx.satoshis)
return _setDispenseStatus(deviceFingerprint, tx, 'insufficientDeposit', txInfo.amount);
// store txHash for later reference
tx.txHash = txInfo.txHash;
// warn about dangerous TX
if (txInfo.fees < RECOMMENDED_FEE)
logger.warn('TXs w/o fee can take forever to confirm!');
// make sure tx isn't already in an acceptable state
if (_checkTx(deviceFingerprint, tx, txInfo))
return;
// update tx status and save first txHash
_setDispenseStatus(deviceFingerprint, tx, 'fullDeposit', txInfo.amount);
// start monitoring TX (instead of an address)
setTimeout(_monitorTx, 300, deviceFingerprint, tx);
});
}
exports.cashOut = function cashOut(deviceFingerprint, tx, cb) {
var tmpInfo = {
label: 'TX ' + Date.now(),
@ -383,19 +319,10 @@ exports.cashOut = function cashOut(deviceFingerprint, tx, cb) {
return cb(new Error(err));
tx.toAddress = address;
tx.tx_type = 'sell';
tx.incoming = false;
db.insertTx(deviceFingerprint, tx, function(err) {
if (err)
return cb(new Error(err));
_setDispenseStatus(deviceFingerprint, tx, 'noDeposit');
// start watching address for incoming txs
_monitorAddress(deviceFingerprint, tx);
// return address to the machine
return cb(null, address);
db.addPendingTx(deviceFingerprint, tx, function(err) {
cb(err, address);
});
});
};