mirror of https://github.com/BTCPrivate/z-nomp.git
More development for payment processing... getting there..
This commit is contained in:
parent
09443b4e6c
commit
191d81bd18
|
@ -80,15 +80,12 @@ function SetupForPool(logger, poolOptions){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var processPayments = function(){
|
var processPayments = function(){
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
|
|
||||||
/* Check redis for all pending block submissions, then pass along each object with:
|
/* Call redis to get an array of rounds - which are coinbase transactions and block heights from submitted
|
||||||
{
|
blocks. */
|
||||||
transHash1: {height: blockHeight1},
|
|
||||||
transHash2: {height: blockHeight2}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
function(callback){
|
function(callback){
|
||||||
|
|
||||||
redisClient.smembers(coin + '_blocks', function(error, results){
|
redisClient.smembers(coin + '_blocks', function(error, results){
|
||||||
|
@ -103,30 +100,25 @@ function SetupForPool(logger, poolOptions){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var txs = {};
|
var rounds = [];
|
||||||
results.forEach(function(item){
|
results.forEach(function(item){
|
||||||
var details = item.split(':');
|
var details = item.split(':');
|
||||||
var txHash = details[0];
|
rounds.push({txHash: details[0], height: details[1], reward: details[2]});
|
||||||
var height = details[1];
|
|
||||||
txs[txHash] = {height: height};
|
|
||||||
});
|
});
|
||||||
callback(null, txs);
|
callback(null, rounds);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/* Receives txs object with key, checks each key (the transHash) with block batch rpc call to daemon.
|
/* Does a batch rpc call to daemon with all the transaction hashes to see if they are confirmed yet.
|
||||||
Each confirmed on get the amount added to transHash object as {amount: amount},
|
It also adds the block reward amount to the round object - which the daemon gives also gives us. */
|
||||||
Non confirmed txHashes get deleted from obj. Then remaining txHashes are passed along
|
function(rounds, callback){
|
||||||
*/
|
|
||||||
function(txs, callback){
|
|
||||||
|
|
||||||
var batchRPCcommand = [];
|
var batchRPCcommand = [];
|
||||||
|
|
||||||
for (var txHash in txs){
|
for (var i = 0; i < rounds.length; i++){
|
||||||
batchRPCcommand.push(['gettransaction', [txHash]]);
|
batchRPCcommand.push(['gettransaction', [rounds[i].txHash]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
daemon.batchCmd(batchRPCcommand, function(error, txDetails){
|
daemon.batchCmd(batchRPCcommand, function(error, txDetails){
|
||||||
|
|
||||||
if (error || !txDetails){
|
if (error || !txDetails){
|
||||||
|
@ -134,57 +126,83 @@ function SetupForPool(logger, poolOptions){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
txDetails.filter(function(tx){
|
//Rounds that are not confirmed yet are removed from the round array
|
||||||
|
//We also get reward amount for each block from daemon reply
|
||||||
|
txDetails.forEach(function(tx){
|
||||||
|
var txResult = tx.result;
|
||||||
var txDetails = tx.result.details[0];
|
var txDetails = tx.result.details[0];
|
||||||
if (txDetails.categery === 'generate'){
|
for (var i = 0; i < rounds.length; i++){
|
||||||
txs[txDetails.txid].amount = txDetails.amount;
|
if (rounds[i].txHash === txResult.txid){
|
||||||
|
rounds[i].amount = txResult.amount;
|
||||||
|
rounds[i].magnitude = rounds[i].reward / txResult.amount;
|
||||||
|
if (txDetails.category !== 'generate')
|
||||||
|
rounds.splice(i, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else delete txs[txDetails.txid];
|
|
||||||
|
|
||||||
});
|
});
|
||||||
if (Object.keys(txs).length === 0){
|
if (rounds.length === 0){
|
||||||
callback('done - no confirmed transactions yet');
|
callback('done - no confirmed transactions yet');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
callback(null, txs);
|
callback(null, rounds);
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/* Use height from each txHash to get worker shares from each round and pass along */
|
/* Does a batch redis call to get shares contributed to each round. Then calculates the reward
|
||||||
function(txs, callback){
|
amount owned to each miner for each round. */
|
||||||
|
function(rounds, callback){
|
||||||
|
|
||||||
var shareLooksup = [];
|
var shareLooksup = [];
|
||||||
for (var hash in txs){
|
for (var i = 0; i < rounds.length; i++){
|
||||||
var height = txs[hash].height;
|
shareLooksup.push(['hgetall', coin + '_shares:round' + rounds[i].height]);
|
||||||
shareLooksup.push(['hgetall', coin + '_shares:round' + height]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
redisClient.multi(shareLooksup).exec(function(error, workerShares){
|
|
||||||
|
|
||||||
|
redisClient.multi(shareLooksup).exec(function(error, allWorkerShares){
|
||||||
if (error){
|
if (error){
|
||||||
callback('done - redis error with multi get rounds share')
|
callback('done - redis error with multi get rounds share')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var balancesForRounds = {};
|
var workerRewards = {};
|
||||||
workerShares.forEach(function(item){
|
|
||||||
for (var worker in item){
|
for (var i = 0; i < rounds.length; i++){
|
||||||
var sharesAdded = parseInt(item[worker]);
|
var round = rounds[i];
|
||||||
if (worker in balancesForRounds)
|
var workerShares = allWorkerShares[i];
|
||||||
balancesForRounds[worker] += sharesAdded;
|
|
||||||
else
|
var reward = round.reward * (1 - processingConfig.feePercent);
|
||||||
balancesForRounds[worker] = sharesAdded;
|
|
||||||
|
var totalShares = 0;
|
||||||
|
for (var worker in workerShares){
|
||||||
|
totalShares += parseInt(workerShares[worker]);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
callback(null, balancesForRounds, txs);
|
for (var worker in workerShares){
|
||||||
|
var singleWorkerShares = parseInt(workerShares[worker]);
|
||||||
|
var percent = singleWorkerShares / totalShares;
|
||||||
|
var workerRewardTotal = (reward * percent) / round.magnitude;
|
||||||
|
workerRewardTotal = Math.floor(workerRewardTotal * round.magnitude) / round.magnitude;
|
||||||
|
if (worker in workerRewards)
|
||||||
|
workerRewards[worker] += workerRewardTotal;
|
||||||
|
else
|
||||||
|
workerRewards[worker] = workerRewardTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.dir(workerRewards);
|
||||||
|
|
||||||
|
callback(null, rounds);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/* Get worker existing balances from coin_balances hashset in redis*/
|
/* Does a batch call to redis to get worker existing balances from coin_balances*/
|
||||||
function(balancesForRounds, txs, callback){
|
function(rounds, callback){
|
||||||
|
/*
|
||||||
var workerAddress = Object.keys(balancesForRounds);
|
var workerAddress = Object.keys(balancesForRounds);
|
||||||
|
|
||||||
redisClient.hmget([coin + '_balances'].concat(workerAddress), function(error, results){
|
redisClient.hmget([coin + '_balances'].concat(workerAddress), function(error, results){
|
||||||
|
@ -200,8 +218,9 @@ function SetupForPool(logger, poolOptions){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null, txs, balancesForRounds)
|
callback(null, rounds, balancesForRounds)
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -211,7 +230,7 @@ function SetupForPool(logger, poolOptions){
|
||||||
when deciding the sent balance, it the difference should be -1*amount they had in db,
|
when deciding the sent balance, it the difference should be -1*amount they had in db,
|
||||||
if not sending the balance, the differnce should be +(the amount they earned this round)
|
if not sending the balance, the differnce should be +(the amount they earned this round)
|
||||||
*/
|
*/
|
||||||
function(fullBalance, txs, callback){
|
function(fullBalance, rounds, callback){
|
||||||
|
|
||||||
/* if payments dont succeed (likely because daemon isnt responding to rpc), then cancel here
|
/* if payments dont succeed (likely because daemon isnt responding to rpc), then cancel here
|
||||||
so that all of this can be tried again when the daemon is working. otherwise we will consider
|
so that all of this can be tried again when the daemon is working. otherwise we will consider
|
||||||
|
@ -223,13 +242,14 @@ function SetupForPool(logger, poolOptions){
|
||||||
|
|
||||||
/* clean DB: update remaining balances in coin_balance hashset in redis
|
/* clean DB: update remaining balances in coin_balance hashset in redis
|
||||||
*/
|
*/
|
||||||
function(balanceDifference, txs, callback){
|
function(balanceDifference, rounds, callback){
|
||||||
|
|
||||||
//SMOVE each tx key from coin_blocks to coin_processedBlocks
|
//SMOVE each tx key from coin_blocks to coin_processedBlocks
|
||||||
//HINCRBY to apply balance different for coin_balances worker1
|
//HINCRBY to apply balance different for coin_balances worker1
|
||||||
|
|
||||||
}
|
}
|
||||||
], function(error, result){
|
], function(error, result){
|
||||||
|
console.log(error);
|
||||||
//log error completion
|
//log error completion
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -68,7 +68,7 @@ module.exports = function(logger, poolConfig){
|
||||||
connection.rename(coin + '_shares:roundCurrent', coin + '_shares:round' + shareData.height, function(result){
|
connection.rename(coin + '_shares:roundCurrent', coin + '_shares:round' + shareData.height, function(result){
|
||||||
console.log('rename result: ' + result);
|
console.log('rename result: ' + result);
|
||||||
});
|
});
|
||||||
connection.sadd([coin + '_blocks', shareData.tx + ':' + shareData.height], function(error, result){
|
connection.sadd([coin + '_blocks', shareData.tx + ':' + shareData.height + ':' + shareData.reward], function(error, result){
|
||||||
if (error)
|
if (error)
|
||||||
logger.error('redis', 'Could not store block data');
|
logger.error('redis', 'Could not store block data');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue