From 5cfc2ba491fe6245f77bebdaaac0203a8975e440 Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Sat, 6 Feb 2016 22:57:49 +0200 Subject: [PATCH 1/3] try locking txs table --- dev/double-spend-scenario.js | 52 ++++++++++++++++++++++++++++++++++++ lib/plugins.js | 4 ++- lib/postgresql_interface.js | 6 ++++- test/plugins.js | 2 +- 4 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 dev/double-spend-scenario.js diff --git a/dev/double-spend-scenario.js b/dev/double-spend-scenario.js new file mode 100644 index 00000000..73e112c3 --- /dev/null +++ b/dev/double-spend-scenario.js @@ -0,0 +1,52 @@ +var db = require('../lib/postgresql_interface') +var connectionString = 'postgres://lamassu:lamassu@localhost/lamassu' +db.init(connectionString) + +var session = { + id: '6ede611c-cd03-11e5-88ee-2b5fcfdb0bc2', + fingerprint: 'xx:xx' +} +var tx = { + fiat: 40, + satoshis: 6980000, + toAddress: '1xxx', + currencyCode: 'CAD', + incoming: false +} + +var tx2 = { + fiat: 0, + satoshis: 6980000, + toAddress: '1xxx', + currencyCode: 'CAD', + incoming: false +} + +db.addOutgoingTx(session, tx, function (err, res) { + console.log('DEBUG1') + console.log(err) + console.log(res) +}) + +setTimeout(function () { + db.addOutgoingTx(session, tx2, function (err, res) { + console.log('DEBUG2') + console.log(err) + console.log(res) + }) +}, 1000) + +var bills = { + uuid: 'c630338c-cd03-11e5-a9df-dbc9be2e9fbb', + currency: 'CAD', + toAddress: '1xxx', + deviceTime: Date.now(), + satoshis: 6980000, + fiat: 40 +} + +/* +db.recordBill(session, bills, function (err) { + console.log(err) +}) +*/ diff --git a/lib/plugins.js b/lib/plugins.js index 0867c43c..a6519956 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -121,7 +121,7 @@ function loadOrConfigPlugin(pluginHandle, pluginType, currency, pluginHandle = loadPlugin(currentName, pluginConfig); currentlyUsedPlugins[pluginType] = currentName logger.debug('plugin(%s) loaded: %s', pluginType, pluginHandle.NAME || - currentName); + currentName); } } @@ -311,6 +311,8 @@ exports.trade = function trade(session, rawTrade, cb) { currencyCode: rawTrade.currency }; + console.log('****************** DEBUG2 *****************') + console.log(db.addOutgoingPending) async.parallel([ async.apply(db.addOutgoingPending, session, tx.currencyCode, tx.toAddress), async.apply(db.recordBill, session, rawTrade) diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index e969f3d8..86935f2b 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -181,6 +181,7 @@ function billsAndTxs(client, session, cb) { } function computeSendAmount(tx, totals) { + console.log('DEBUG10') var fiatRemaining = (tx.fiat || totals.billsFiat) - totals.txFiat; var satoshisRemaining = (tx.satoshis || totals.billsSatoshis) - totals.txSatoshis; @@ -303,6 +304,8 @@ function insertTx(client, session, incoming, tx, satoshis, fiat, stage, tx.error ]; + console.log('DEBUG11') + query(client, getInsertQuery('transactions', fields, true), values, function(err, results) { if (err) return cb(err); @@ -347,6 +350,7 @@ exports.addOutgoingTx = function addOutgoingTx(session, tx, cb) { if (cerr) return cb(cerr); async.series([ async.apply(silentQuery, client, 'BEGIN'), + async.apply(silentQuery, client, 'LOCK TABLE transactions NOWAIT'), async.apply(insertOutgoingCompleteTx, client, session, tx), async.apply(removePendingTx, client, session), async.apply(buildOutgoingTx, client, session, tx) @@ -357,7 +361,7 @@ exports.addOutgoingTx = function addOutgoingTx(session, tx, cb) { } silentQuery(client, 'COMMIT', [], function() { done(); - var toSend = results[3]; + var toSend = results[4]; cb(null, toSend); }); }); diff --git a/test/plugins.js b/test/plugins.js index bf8aeaa4..206a7e41 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -192,7 +192,7 @@ describe('Plugins', function() { describe('Send Bitcoins', function() { before(function() { - plugins.trade({currency: 'USD', satoshis: 1e7}, db.FINGERPRINT_NEW); + plugins.trade('123', {currency: 'USD', satoshis: 1e7, toAddress: '1xxx'}, function() {}); }); it('should send bitcoins successfully', function(done) { From 5b5fc8b8104199de2dc19270c05453b676da584c Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Sun, 7 Feb 2016 02:40:20 +0200 Subject: [PATCH 2/3] fix postgres locking issue which could lead to rare double send --- dev/double-spend-scenario.js | 10 +++++++++- lib/postgresql_interface.js | 5 +---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/dev/double-spend-scenario.js b/dev/double-spend-scenario.js index 73e112c3..eef96ccb 100644 --- a/dev/double-spend-scenario.js +++ b/dev/double-spend-scenario.js @@ -28,13 +28,21 @@ db.addOutgoingTx(session, tx, function (err, res) { console.log(res) }) +db.addOutgoingTx(session, tx2, function (err, res) { + console.log('DEBUG2') + console.log(err) + console.log(res) +}) + +/* setTimeout(function () { db.addOutgoingTx(session, tx2, function (err, res) { console.log('DEBUG2') console.log(err) console.log(res) }) -}, 1000) +}, 0) +*/ var bills = { uuid: 'c630338c-cd03-11e5-a9df-dbc9be2e9fbb', diff --git a/lib/postgresql_interface.js b/lib/postgresql_interface.js index 86935f2b..ca58093d 100644 --- a/lib/postgresql_interface.js +++ b/lib/postgresql_interface.js @@ -181,7 +181,6 @@ function billsAndTxs(client, session, cb) { } function computeSendAmount(tx, totals) { - console.log('DEBUG10') var fiatRemaining = (tx.fiat || totals.billsFiat) - totals.txFiat; var satoshisRemaining = (tx.satoshis || totals.billsSatoshis) - totals.txSatoshis; @@ -304,8 +303,6 @@ function insertTx(client, session, incoming, tx, satoshis, fiat, stage, tx.error ]; - console.log('DEBUG11') - query(client, getInsertQuery('transactions', fields, true), values, function(err, results) { if (err) return cb(err); @@ -350,7 +347,7 @@ exports.addOutgoingTx = function addOutgoingTx(session, tx, cb) { if (cerr) return cb(cerr); async.series([ async.apply(silentQuery, client, 'BEGIN'), - async.apply(silentQuery, client, 'LOCK TABLE transactions NOWAIT'), + async.apply(silentQuery, client, 'LOCK TABLE transactions'), async.apply(insertOutgoingCompleteTx, client, session, tx), async.apply(removePendingTx, client, session), async.apply(buildOutgoingTx, client, session, tx) From 30ba92b1dcd4ebc7999b0d68a26ed7538e676481 Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Sun, 7 Feb 2016 02:49:39 +0200 Subject: [PATCH 3/3] take out debugging --- lib/plugins.js | 4 +--- test/plugins.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/plugins.js b/lib/plugins.js index a6519956..0867c43c 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -121,7 +121,7 @@ function loadOrConfigPlugin(pluginHandle, pluginType, currency, pluginHandle = loadPlugin(currentName, pluginConfig); currentlyUsedPlugins[pluginType] = currentName logger.debug('plugin(%s) loaded: %s', pluginType, pluginHandle.NAME || - currentName); + currentName); } } @@ -311,8 +311,6 @@ exports.trade = function trade(session, rawTrade, cb) { currencyCode: rawTrade.currency }; - console.log('****************** DEBUG2 *****************') - console.log(db.addOutgoingPending) async.parallel([ async.apply(db.addOutgoingPending, session, tx.currencyCode, tx.toAddress), async.apply(db.recordBill, session, rawTrade) diff --git a/test/plugins.js b/test/plugins.js index 206a7e41..bf8aeaa4 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -192,7 +192,7 @@ describe('Plugins', function() { describe('Send Bitcoins', function() { before(function() { - plugins.trade('123', {currency: 'USD', satoshis: 1e7, toAddress: '1xxx'}, function() {}); + plugins.trade({currency: 'USD', satoshis: 1e7}, db.FINGERPRINT_NEW); }); it('should send bitcoins successfully', function(done) {