public async Task UpdateBalancesAsync(IDbConnection con, IDbTransaction tx, PoolConfig poolConfig, IPayoutHandler payoutHandler, Block block, decimal blockReward) { // calculate rewards var rewards = new Dictionary <string, decimal>(); var shareCutOffDate = CalculateRewards(poolConfig, block, blockReward, rewards); // update balances foreach (var address in rewards.Keys) { var amount = rewards[address]; if (amount > 0) { logger.Info(() => $"Adding {payoutHandler.FormatAmount(amount)} to balance of {address} for block {block.BlockHeight}"); await balanceRepo.AddAmountAsync(con, tx, poolConfig.Id, address, amount, $"Reward for block {block.BlockHeight}"); } } // delete discarded shares if (shareCutOffDate.HasValue) { var cutOffCount = await shareRepo.CountSharesSoloBeforeCreatedAsync(con, tx, poolConfig.Id, block.Miner, shareCutOffDate.Value); if (cutOffCount > 0) { #if !DEBUG logger.Info(() => $"Deleting {cutOffCount} discarded shares for {block.Miner}"); await shareRepo.DeleteSharesSoloBeforeCreatedAsync(con, tx, poolConfig.Id, block.Miner, shareCutOffDate.Value); #endif } } }
public Task UpdateBalancesAsync(IDbConnection con, IDbTransaction tx, PoolConfig poolConfig, IPayoutHandler payoutHandler, Block block, decimal blockReward) { var payoutConfig = poolConfig.PaymentProcessing.PayoutSchemeConfig; // PPLNS window (see https://bitcointalk.org/index.php?topic=39832) var window = payoutConfig?.ToObject <Config>()?.Factor ?? 2.0m; // calculate rewards var shares = new Dictionary <string, double>(); var rewards = new Dictionary <string, decimal>(); var shareCutOffDate = CalculateRewards(poolConfig, window, block, blockReward, shares, rewards); // update balances foreach (var address in rewards.Keys) { var amount = rewards[address]; if (amount > 0) { logger.Info(() => $"Adding {payoutHandler.FormatAmount(amount)} to balance of {address} for {FormatUtil.FormatQuantity(shares[address])} ({shares[address]}) shares for block {block.BlockHeight}"); balanceRepo.AddAmount(con, tx, poolConfig.Id, poolConfig.Coin.Type, address, amount, $"Reward for {FormatUtil.FormatQuantity(shares[address])} shares for block {block.BlockHeight}"); } } // delete discarded shares if (shareCutOffDate.HasValue) { var cutOffCount = shareRepo.CountSharesBeforeCreated(con, tx, poolConfig.Id, shareCutOffDate.Value); if (cutOffCount > 0) { LogDiscardedShares(poolConfig, block, shareCutOffDate.Value); #if !DEBUG logger.Info(() => $"Deleting {cutOffCount} discarded shares before {shareCutOffDate.Value:O}"); shareRepo.DeleteSharesBeforeCreated(con, tx, poolConfig.Id, shareCutOffDate.Value); #endif } } // diagnostics var totalShareCount = shares.Values.ToList().Sum(x => new decimal(x)); var totalRewards = rewards.Values.ToList().Sum(x => x); if (totalRewards > 0) { logger.Info(() => $"{FormatUtil.FormatQuantity((double) totalShareCount)} ({Math.Round(totalShareCount, 2)}) shares contributed to a total payout of {payoutHandler.FormatAmount(totalRewards)} ({totalRewards / blockReward * 100:0.00}% of block reward) to {rewards.Keys.Count} addresses"); } return(Task.FromResult(true)); }
public Task UpdateBalancesAsync(IDbConnection con, IDbTransaction tx, PoolConfig poolConfig, IPayoutHandler payoutHandler, Block block, decimal blockReward) { var payoutConfig = poolConfig.PaymentProcessing.PayoutSchemeConfig; // PPLNS window (see https://bitcointalk.org/index.php?topic=39832) var window = payoutConfig?.ToObject <Config>()?.Factor ?? 2.0m; // calculate rewards var shares = new Dictionary <string, ulong>(); var rewards = new Dictionary <string, decimal>(); var shareCutOffDate = CalculateRewards(poolConfig, window, block, blockReward, shares, rewards); // update balances foreach (var address in rewards.Keys) { var amount = rewards[address]; if (amount > 0) { logger.Info(() => $"Adding {payoutHandler.FormatAmount(amount)} to balance of {address} for {shares[address]} shares"); balanceRepo.AddAmount(con, tx, poolConfig.Id, poolConfig.Coin.Type, address, amount); } } // delete obsolete shares if (shareCutOffDate.HasValue) { var cutOffCount = shareRepo.CountPoolSharesBefore(con, tx, poolConfig.Id, shareCutOffDate.Value); if (cutOffCount > 0) { logger.Info(() => $"Deleting {cutOffCount} obsolete shares before {shareCutOffDate.Value}"); shareRepo.DeletePoolSharesBefore(con, tx, poolConfig.Id, shareCutOffDate.Value); } //logger.Info(() => $"Shares before {shareCutOffDate.Value} can be deleted"); } // diagnostics var totalShareCount = shares.Values.ToList().Sum(x => new decimal(x)); var totalRewards = rewards.Values.ToList().Sum(x => x); if (totalRewards > 0) { logger.Info(() => $"{totalShareCount} shares contributed to a total payout of {payoutHandler.FormatAmount(totalRewards)} ({totalRewards / blockReward * 100:0.00}% of block reward)"); } return(Task.FromResult(true)); }
public async Task UpdateBalancesAsync(IDbConnection con, IDbTransaction tx, PoolConfig poolConfig, IPayoutHandler payoutHandler, Block block, decimal blockReward) { var payoutConfig = poolConfig.PaymentProcessing.PayoutSchemeConfig; var window = payoutConfig?.ToObject <Config>()?.Factor ?? 2.0m; var shares = new Dictionary <string, double>(); var rewards = new Dictionary <string, decimal>(); var shareCutOffDate = await CalculateRewardsAsync(poolConfig, block, blockReward, shares, rewards); // update balances foreach (var address in rewards.Keys) { var amount = rewards[address]; if (amount > 0) { logger.Info(() => $"Adding {payoutHandler.FormatAmount(amount)} to balance of {address} for {FormatUtil.FormatQuantity(shares[address])} ({shares[address]}) shares for block {block.BlockHeight}"); await balanceRepo.AddAmountAsync(con, tx, poolConfig.Id, address, amount, $"Reward for {FormatUtil.FormatQuantity(shares[address])} shares for block {block.BlockHeight}"); } } // delete discarded shares if (shareCutOffDate.HasValue) { var cutOffCount = await shareRepo.CountSharesBeforeCreatedAsync(con, tx, poolConfig.Id, shareCutOffDate.Value); if (cutOffCount > 0) { await LogDiscardedSharesAsync(poolConfig, block, shareCutOffDate.Value); logger.Info(() => $"Deleting {cutOffCount} discarded shares before {shareCutOffDate.Value:O}"); await shareRepo.DeleteSharesBeforeCreatedAsync(con, tx, poolConfig.Id, shareCutOffDate.Value); } } // diagnostics var totalShareCount = shares.Values.ToList().Sum(x => new decimal(x)); var totalRewards = rewards.Values.ToList().Sum(x => x); if (totalRewards > 0) { logger.Info(() => $"{FormatUtil.FormatQuantity((double) totalShareCount)} ({Math.Round(totalShareCount, 2)}) shares contributed to a total payout of {payoutHandler.FormatAmount(totalRewards)} ({totalRewards / blockReward * 100:0.00}% of block reward) to {rewards.Keys.Count} addresses"); } }