From 9a618136786ea869a33e138bac47f5ee440d536f Mon Sep 17 00:00:00 2001 From: Joshua Yabut Date: Tue, 27 Dec 2016 11:42:48 -0500 Subject: [PATCH] Bugfix #40: Payment processor doesn't know about coinbase-xfer cycling (#53) --- libs/paymentProcessor.js | 66 ++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/libs/paymentProcessor.js b/libs/paymentProcessor.js index 101be33..d75d0c3 100644 --- a/libs/paymentProcessor.js +++ b/libs/paymentProcessor.js @@ -152,39 +152,43 @@ function SetupForPool(logger, poolOptions, setupFinished){ async.parallel([validateAddress, validateTAddress, validateZAddress, getBalance], asyncComplete); //get t_address coinbalance - function listUnspent (addr, minConf, callback) { + function listUnspent (addr, minConf, displayBool, callback) { daemon.cmd('listunspent', [minConf, 99999999999, [addr]], function (result) { //Check if payments failed because wallet doesn't have enough coins to pay for tx fees - if (result.error) { + if (result[0].error) { logger.error(logSystem, logComponent, 'Error trying to get coin balance with RPC listunspent.' - + JSON.stringify(result.error)); + + JSON.stringify(result[0].error)); callback = function (){}; callback(true); } else { var tBalance = 0; for (var i = 0, len = result[0].response.length; i < len; i++) { - tBalance = tBalance + result[0].response[i].amount * magnitude; + tBalance = tBalance + (result[0].response[i].amount * magnitude); } - logger.debug(logSystem, logComponent, addr + ' contains a balance of: ' + (tBalance / magnitude)); - callback(null, tBalance); + if (displayBool === true) { + logger.special(logSystem, logComponent, addr + ' contains a balance of ' + (tBalance / magnitude).toFixed(8)); + } + callback(null, tBalance.toFixed(8)); } }); } // get z_address coinbalance - function listUnspentZ (addr, callback) { - daemon.cmd('z_getbalance', [addr, 3], function (result) { + function listUnspentZ (addr, minConf, displayBool, callback) { + daemon.cmd('z_getbalance', [addr, minConf], function (result) { //Check if payments failed because wallet doesn't have enough coins to pay for tx fees - if (result.error) { - logger.error(logSystem, logComponent, 'Error trying to get coin balance with RPC z_getbalance.' + JSON.stringify(result.error)); + if (result[0].error) { + logger.error(logSystem, logComponent, 'Error trying to get coin balance with RPC z_getbalance.' + JSON.stringify(result[0].error)); callback = function (){}; callback(true); } else { var zBalance = result[0].response; - logger.debug(logSystem, logComponent, addr + ' contains a balance of: ' + (zBalance)); - callback(null, zBalance); + if (displayBool === true) { + logger.special(logSystem, logComponent, addr + ' contains a balance of ' + (zBalance).toFixed(8)); + } + callback(null, (zBalance * magnitude).toFixed(8)); } }); } @@ -193,7 +197,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ function sendTToZ (callback, tBalance) { if (callback === true) return; - if ((tBalance - 10000) / magnitude < 0) + if ((tBalance - 10000) < 0) return; daemon.cmd('z_sendmany', [poolOptions.address, [{'address': poolOptions.zAddress, 'amount': ((tBalance - 10000) / magnitude)}]], @@ -205,7 +209,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ callback(true); } else { - logger.debug(logSystem, logComponent, 'Sent t_address balance to z_address: ' + ((tBalance - 10000) / magnitude)); + logger.special(logSystem, logComponent, 'Sent tAddress balance to z_address: ' + ((tBalance - 10000) / magnitude)); callback = function (){}; callback(null); } @@ -217,10 +221,10 @@ function SetupForPool(logger, poolOptions, setupFinished){ function sendZToT (callback, zBalance) { if (callback === true) return; - if ((zBalance) - (10000 / magnitude) < 0) + if ((zBalance - 10000) < 0) return; daemon.cmd('z_sendmany', [poolOptions.zAddress, - [{'address': poolOptions.tAddress, 'amount': ((zBalance) - (10000 / magnitude))}]], + [{'address': poolOptions.tAddress, 'amount': ((zBalance - 10000) / magnitude)}]], function (result) { //Check if payments failed because wallet doesn't have enough coins to pay for tx fees if (result.error) { @@ -230,7 +234,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ callback(true); } else { - logger.debug(logSystem, logComponent, 'Sent z_address balance to t_address: ' + ((zBalance) - (10000 / magnitude))); + logger.special(logSystem, logComponent, 'Sent zAddress balance to t_address: ' + ((zBalance - 10000) / magnitude)); callback = function (){}; callback(null); } @@ -241,9 +245,9 @@ function SetupForPool(logger, poolOptions, setupFinished){ // run coinbase coin transfers every x minutes var interval = poolOptions.walletInterval * 60 * 1000; // run every x minutes setInterval(function() { - listUnspent(poolOptions.address, 100, sendTToZ); - listUnspentZ(poolOptions.zAddress, sendZToT); - listUnspent(poolOptions.tAddress, 3, function (){}); + listUnspent(poolOptions.address, 1, true, sendTToZ); + listUnspentZ(poolOptions.zAddress, 1, true, sendZToT); + listUnspent(poolOptions.tAddress, 1, true, function (){}); }, interval); @@ -293,8 +297,6 @@ function SetupForPool(logger, poolOptions, setupFinished){ return; } - - var workers = {}; for (var w in results[0]){ workers[w] = {balance: coinsToSatoshies(parseFloat(results[0][w]))}; @@ -314,6 +316,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ }); }, + /* Does a batch rpc call to daemon with all the transaction hashes to see if they are confirmed yet. It also adds the block reward amount to the round object - which the daemon gives also gives us. */ function(workers, rounds, callback){ @@ -366,7 +369,6 @@ function SetupForPool(logger, poolOptions, setupFinished){ return tx.address === poolOptions.address; })[0]; - if (!generationTx && tx.result.details.length === 1){ generationTx = tx.result.details[0]; } @@ -411,8 +413,20 @@ function SetupForPool(logger, poolOptions, setupFinished){ } }); - - callback(null, workers, rounds, addressAccount); + // check if we have enough tAddress funds to send payments + var totalOwed = 0; + for (var i = 0; i < rounds.length; i++) { + totalOwed = totalOwed + (rounds[i].reward * magnitude); + } + listUnspent(poolOptions.tAddress, 1, false, function (error, tBalance){ + if (tBalance < totalOwed) { + logger.error(logSystem, logComponent, (tBalance / magnitude).toFixed(8) + ' is not enough tAddress funds to process ' + (totalOwed / magnitude).toFixed(8) + ' of payments. (Possibly due to pending txs)'); + return callback(true); + } + else { + callback(null, workers, rounds, addressAccount); + } + }) }); }, @@ -523,7 +537,7 @@ function SetupForPool(logger, poolOptions, setupFinished){ callback(true); } else { - logger.debug(logSystem, logComponent, 'Sent out a total of ' + (totalSent / magnitude) + logger.special(logSystem, logComponent, 'Sent out a total of ' + (totalSent / magnitude) + ' to ' + Object.keys(addressAmounts).length + ' workers'); if (withholdPercent > 0) { logger.warning(logSystem, logComponent, 'Had to withhold ' + (withholdPercent * 100)