Sep 11, 2014
initial commit
1
var poolConfig = require (' ./burst-pool-config' );
2
var poolShare = require (' ./burst-pool-share' );
3
var poolProtocol = require (' ./burst-pool-protocol' );
4
var poolSession = require (' ./burst-pool-session' );
5
var async = require (' async' );
6
var fs = require (' fs' );
7
var jsonFormat = require (' prettyjson' );
8
9
var blockPaymentList = [];
10
var pendingPaymentList = {};
11
var sentPaymentList = [];
12
13
function satoshiToDecimal (sat ){
14
if (typeof sat === ' undefined' || isNaN (sat)){
15
return 0.0 ;
16
}
17
return parseFloat (sat)/ 100000000.0 ;
18
}
19
20
function decimalToSatoshi (amount ){
21
if (typeof amount === ' undefined' || isNaN (amount)){
22
return 0 ;
23
}
24
return parseInt (parseFloat (amount)* 100000000 );
25
}
Sep 11, 2014
initial commit
27
28
BlockPayment = function (height , shareList ){
29
this .shareList = shareList; // {accountId, share}
30
this .height = height;
31
this .totalShare = 0 ;
32
this .allocatedFund = 0 ;
33
34
for (var i in this .shareList ){
35
this .totalShare += this .shareList [i].share ;
36
}
37
};
38
39
function assignCumulativeFund (height , amount ){
40
try {
41
var fundedList = [];
42
var totalScale = 0 ;
43
// calculate funds allocation weight each block by applying cumulative reduction factor
44
blockPaymentList .forEach (function (payBlock ){
45
var reduction = poolConfig .cumulativeFundReduction ;
46
if (reduction > 1.0 ){
47
reduction = 1.0 ;
48
}
49
else if (reduction <= 0.0 ){
50
reduction = 0.01 ;
51
}
52
if (payBlock .height <= height){
53
var fundedItem = {
54
blockPayment : payBlock, // is this reference ??
55
scale : Math .pow (reduction,height- payBlock .height )
56
};
57
totalScale += fundedItem .scale ;
58
fundedList .push (fundedItem);
59
}
60
});
61
62
if (totalScale > 0 ){
63
// apply fund allocation weight to each block
64
fundedList .forEach (function (fundedItem ){
65
fundedItem .blockPayment .allocatedFund += (amount * fundedItem .scale ) / totalScale;
66
poolProtocol .clientLog (' Payment Block#' + fundedItem .blockPayment .height + ' allocated fund = ' + fundedItem .blockPayment .allocatedFund .toFixed (2 ));
67
});
68
}
69
}
70
catch (e){
71
console .log (e);
72
console .trace ();
73
}
74
}
75
function distributeShareToPayment (){
76
var accountList = {};
77
blockPaymentList .forEach (function (blockPayment ){
78
// calculate payment amount for each account
Nov 26, 2016
Payments On New Block Rewrite
132
function flushPaymentList (done ){
133
try {
134
var paymentItems = {};
135
// calculate txFee
136
// var i = 0;
137
// var totalPaid = 0;
138
for (var payAccountId in pendingPaymentList){
139
140
if (! paymentItems .hasOwnProperty (payAccountId)){
141
paymentItems[payAccountId] = {
142
amount : pendingPaymentList[payAccountId],
143
txFee : 0
144
}
145
}
146
else {
147
paymentItems[payAccountId].amount += paymentItems[payAccountId .txFee ];
148
}
149
150
paymentItems[payAccountId].txFee = 1 ;
151
paymentItems[payAccountId].amount = paymentItems[payAccountId].amount - paymentItems[payAccountId].txFee ;
152
}
153
154
// clear blockpayment list, all data has been moved to paymentItems
155
pendingPaymentList = {};
156
157
// send payment for each pending item
158
var accountList = [];
159
for (var accountId in paymentItems){
160
var paymentData = {
161
accountId : accountId,
162
amount : paymentItems[accountId].amount ,
163
txFee : paymentItems[accountId].txFee
164
};
165
accountList .push (paymentData);
166
}
167
168
// ----- DEBUG ONLY
169
var pendingTxData = JSON .stringify (accountList, null , 4 );
170
fs .writeFile (' last-pay-calc.json' ,pendingTxData, function (err ){});
171
// ----------144-160 changed
172
173
var clearPayout = poolConfig .clearingMinPayout ;
174
175
var failedTxList = [];
176
177
async .each (accountList,
178
179
180
181
function (pay ,callback ){
182
183
if (pay .amount > clearPayout ){
184
185
sendPayment (pay .accountId , pay .amount , pay .txFee , failedTxList, sentPaymentList, function (){
186
});
187
188
console .log (pay .accountId + ' payment amount ' + pay .amount + ' is paid ' );
189
190
}
191
else {
192
console .log (pay .accountId + ' payment amount ' + pay .amount + ' is below payment threshold ' );
193
failedTxList .push (pay);
194
}
195
196
callback ();
197
},
198
function (err ){
199
failedTxList .forEach (function (tx ){
200
pendingPaymentList[tx .accountId ] = tx .amount + tx .txFee ;
201
console .log (' storing pending payment ' + (tx .amount + tx .txFee )+ ' for ' + tx .accountId );
202
});
203
204
saveSessionAsync (function (err ){
205
poolProtocol .getWebsocket ().emit (' pending' ,JSON .stringify (pendingPaymentList));
206
poolProtocol .getWebsocket ().emit (' sentList' ,JSON .stringify (sentPaymentList));
207
done ();
208
});
209
}
210
);
211
}
212
catch (e){
213
console .log (e);
214
console .trace ();
215
}
Sep 11, 2014
initial commit
216
}
217
218
function sendPayment (toAccountId , amount , txFee , failedTxList , sentPaymentList , done ){
219
var floatAmount = amount .toFixed (2 );
220
if (poolConfig .enablePayment === true ){
221
poolProtocol .httpPostForm (' sendMoney' ,
222
{
223
recipient : toAccountId,
224
deadline : poolConfig .defaultPaymentDeadline ,
225
feeNQT : decimalToSatoshi (txFee),
226
amountNQT : decimalToSatoshi (amount),
227
secretPhrase: poolConfig .poolPvtKey
228
},
229
function (error , res , body ){
230
231
var result = {
232
status : false ,
233
txid : ' ' ,
234
sendTime : 0 ,
235
accountId : toAccountId,
236
amount : amount,
237
txFee : txFee
238
};
239
240
if (! error && res .statusCode == 200 ) {
241
var response = JSON .parse (body);
242
if (response .hasOwnProperty (' transaction' )){
243
result .status = true ;
244
result .txid = response .transaction ;
245
result .sendTime = new Date ().getTime ();
246
247
poolProtocol .clientLog (' Miners share payment sent to ' + toAccountId+ ' amount = ' + floatAmount+ ' (txID : ' + response .transaction + ' )' );
248
console .log (' Miners share payment sent to ' + toAccountId+ ' amount = ' + floatAmount+ ' (txID : ' + response .transaction + ' )' );
249
sentPaymentList .push (result);
250
if (sentPaymentList .length > poolConfig .maxRecentPaymentHistory ){
251
var toRemove = sentPaymentList .length - poolConfig .maxRecentPaymentHistory ;
252
sentPaymentList .splice (0 ,toRemove);
253
}
254
poolSession .getState ().current .totalPayments += amount;
255
}
256
}
257
else {
258
console .log (' Failed to send miner payment to ' + toAccountId+ ' amount = ' + floatAmount);
259
failedTxList .push (result);
260
}
261
done ();
262
}
263
);
264
console .log (' submitted transaction request, miner payment for ' + toAccountId+ ' amount = ' + floatAmount);
265
}
266
else {
267
done ();
268
}
269
}
270
271
function getPoolBalance (done ){
272
poolProtocol .httpPostForm (' getGuaranteedBalance' ,
273
{
274
account: poolConfig .poolPublic ,
275
numberOfConfirmations: poolConfig .blockMature
276
},
277
function (error , res , body ){
278
if (! error && res .statusCode == 200 ) {
279
var response = JSON .parse (body);
280
if (response .hasOwnProperty (' guaranteedBalanceNQT' )){
281
var balanceResult = parseFloat (response .guaranteedBalanceNQT )/ 100000000.0 ;
282
var result = {
283
status : true ,
284
balance : balanceResult
285
};
286
console .log (' Pool Balance = ' + balanceResult+ " BURST" );
287
done (result);
288
}
289
else {
290
poolProtocol .clientLog (" API result error on get pool funds query" );
291
done ({status: false });
292
}
293
}
294
else {
295
console .log (" http error on get pool funds query" );
296
console .log (error);
297
done ({status: false });
298
}
299
}
300
);
301
}
302
303
function saveSession () {
304
var data = {
305
blockPaymentList : blockPaymentList,
306
pendingPaymentList : pendingPaymentList,
307
sentPaymentList : sentPaymentList
308
};
309
if (data .sentPaymentList .length > poolConfig .maxRecentPaymentHistory ){
310
var toRemove = data .sentPaymentList .length - poolConfig .maxRecentPaymentHistory ;
311
data .sentPaymentList .splice (0 ,toRemove);
312
}
313
314
var jsonData = JSON .stringify (data,null ,2 );
315
fs .writeFileSync (' pool-payments.json' , jsonData);
316
}
317
318
function saveSessionAsync (done ) {
319
var data = {
320
blockPaymentList : blockPaymentList,
321
pendingPaymentList : pendingPaymentList,
322
sentPaymentList : sentPaymentList
323
};
324
if (data .sentPaymentList .length > poolConfig .maxRecentPaymentHistory ){
325
var toRemove = data .sentPaymentList .length - poolConfig .maxRecentPaymentHistory ;
326
data .sentPaymentList .splice (0 ,toRemove);
327
}
328
329
var jsonData = JSON .stringify (data,null ,2 );
330
fs .writeFile (' pool-payments.json' , jsonData, function (err ){
331
done (err);
332
});
333
}
334
335
function getPendingPaymentAmount (){
336
var total = 0 ;
337
for (var accountId in pendingPaymentList){
338
total += pendingPaymentList[accountId];
339
}
340
341
return total;
342
}
343
344
function getBalance (done ){
345
getPoolBalance (function (res ){
346
var pendingPaymentAmount = getPendingPaymentAmount ();
347
if (res .status === true ){
348
console .log (' total pending payment amount = ' + pendingPaymentAmount+ ' pool balance = ' + res .balance );
349
res .netBalance = res .balance - pendingPaymentAmount;
350
res .pendingBalance = pendingPaymentAmount;
351
}
352
else {
353
res .netBalance = 0 ;
354
res .pendingBalance = pendingPaymentAmount;
355
}
356
done (res);
357
});
358
}
Nov 26, 2016
Payments On New Block Rewrite
369
var result = {
370
status : true ,
371
burstname : response .rewardRecipient ,
372
Addr : burstID
373
};
374
375
done (result);
376
}
377
else {
378
// poolProtocol.clientLog("API result error on get pool funds query");
379
var result = {
380
status : true ,
381
burstname : burstID,
382
Addr : burstID
383
};
384
done (result);
385
}
386
}
387
else {
388
// console.log("http error on get pool funds query");
389
console .log (error);
390
var result = {
391
status : true ,
392
burstname : burstID,
393
Addr : burstID
394
395
};
396
done (result);
397
}
398
}
399
);
400
}
401
function getDateTime () {
402
var date = new Date ();
403
var hour = date .getHours ();
404
hour = (hour < 10 ? " 0" : " " ) + hour;
405
var min = date .getMinutes ();
406
min = (min < 10 ? " 0" : " " ) + min;
407
var sec = date .getSeconds ();
408
sec = (sec < 10 ? " 0" : " " ) + sec;
409
var year = date .getFullYear ();
410
var month = date .getMonth () + 1 ;
411
month = (month < 10 ? " 0" : " " ) + month;
412
var day = date .getDate ();
413
day = (day < 10 ? " 0" : " " ) + day;
414
return hour + " :" + min + " :" + sec;
415
}
Nov 26, 2016
Payments On New Block Rewrite
434
if (blockInfo .status === true ){
435
436
var lastBlockWinner = blockInfo .data .generatorRS ;
437
var blockReward = blockInfo .data .blockReward ;
438
var totalBlockReward = 0 ;
439
var txFeeReward = 0 ;
440
if (blockInfo .data .totalFeeNQT > 0 ){
441
txFeeReward = (blockInfo .data .totalFeeNQT / 100000000 );
442
totalBlockReward = (parseFloat (blockReward) + parseFloat (txFeeReward));
443
444
}else {
445
446
totalBlockReward = blockReward;
447
txFeeReward = 0 ;
448
}
449
poolProtocol .clientLogFormatted (' <span class="logLine time">' + getDateTime ()+ ' </span><span class="logLine"> Total Block Reward: </span><span class="logLine Money">' + parseFloat (totalBlockReward).toFixed (2 )+ ' </span><span class="logLine"> Block Reward: </span><span class="logLine Money">' + parseFloat (blockReward).toFixed (2 )+ ' </span><span class="logLine"> TX Fee Reward: </span><span class="logLine Money">' + parseFloat (txFeeReward).toFixed (2 )+ ' </span>' );
450
451
getRewardRecipient (lastBlockWinner,function (rewardRecip ){
452
var isPoolWinner = ' We Lost -' ;
453
454
if (rewardRecip .burstname == poolConfig .poolPublic ){
455
isPoolWinner = ' We Won -' ;
456
457
getBalance (function (res ){
458
if (res .status === true ){
459
var minPayout = poolConfig .minimumPayout ;
460
var poolFund = res .balance ;
461
var pendingPayment = res .pendingBalance ;
462
var poolFundWithPayments = res .netBalance ;
Sep 11, 2014
initial commit
496
}
497
catch (e){
498
console .log (e);
499
console .trace ();
500
}
501
}
502
503
module .exports = {
504
updateByNewBlock : updateByNewBlock,
505
getBalance : getBalance,
506
saveSession : saveSession,
507
loadSession : function (done ) {
508
if ( fs .existsSync (' pool-payments.json' )) {
509
fs .readFile (' pool-payments.json' , function (err , data ) {
510
try {
511
var loadedData = JSON .parse (data);
512
if (loadedData .hasOwnProperty (' blockPaymentList' )){
513
blockPaymentList = loadedData .blockPaymentList ;
514
}
515
if (loadedData .hasOwnProperty (' pendingPaymentList' )){
516
pendingPaymentList = loadedData .pendingPaymentList ;
517
}
518
if (loadedData .hasOwnProperty (' sentPaymentList' )){
519
sentPaymentList = loadedData .sentPaymentList ;
520
if (sentPaymentList .length > poolConfig .maxRecentPaymentHistory ){
521
var toRemove = sentPaymentList .length - poolConfig .maxRecentPaymentHistory ;
522
sentPaymentList .splice (0 ,toRemove);
523
}
524
}
525
}
526
catch (e){
527
console .log (e);
528
console .trace ();
529
}
530
done ();
531
});
532
}
533
else {
534
done ();
535
}
536
},
537
getPaidList : function (){
538
return sentPaymentList;
539
}