Support per balance transactions in PayoutHandlerBase
@@ -105,8 +105,11 @@ public abstract class PayoutHandlerBase
return blockRewardRemaining;
}
- protected virtual async Task PersistPaymentsAsync(Balance[] balances, string transactionConfirmation)
+ protected async Task PersistPaymentsAsync(Balance[] balances, string transactionConfirmation)
{
+ Contract.RequiresNonNull(balances);
+ Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(transactionConfirmation));
+
var coin = poolConfig.Template.As<CoinTemplate>();
try
@@ -149,6 +152,58 @@ public abstract class PayoutHandlerBase
}
}
+ protected async Task PersistPaymentsAsync(Balance[] balances, string[] transactionConfirmations)
+ {
+ Contract.RequiresNonNull(balances);
+ Contract.RequiresNonNull(transactionConfirmations);
+ Contract.Requires<ArgumentException>(balances.Length > 0);
+ Contract.Requires<ArgumentException>(balances.Length == transactionConfirmations.Length);
+
+ var coin = poolConfig.Template.As<CoinTemplate>();
+
+ try
+ {
+ await faultPolicy.ExecuteAsync(async () =>
+ {
+ await cf.RunTx(async (con, tx) =>
+ {
+ for(var i = 0; i < balances.Length; i++)
+ {
+ var balance = balances[i];
+ var transactionConfirmation = transactionConfirmations[i];
+
+ if(!string.IsNullOrEmpty(transactionConfirmation) && poolConfig.RewardRecipients.All(x => x.Address != balance.Address))
+ {
+ // record payment
+ var payment = new Payment
+ {
+ PoolId = poolConfig.Id,
+ Coin = coin.Symbol,
+ Address = balance.Address,
+ Amount = balance.Amount,
+ Created = clock.Now,
+ TransactionConfirmationData = transactionConfirmation
+ };
+
+ await paymentRepo.InsertAsync(con, tx, payment);
+ }
+
+ // reset balance
+ logger.Debug(() => $"[{LogCategory}] Resetting balance of {balance.Address}");
+ await balanceRepo.AddAmountAsync(con, tx, poolConfig.Id, balance.Address, -balance.Amount, "Balance reset after payment");
+ }
+ });
+ });
+ }
+
+ catch(Exception ex)
+ {
+ logger.Error(ex, () => $"[{LogCategory}] Failed to persist the following payments: " +
+ $"{JsonConvert.SerializeObject(balances.Where(x => x.Amount > 0).ToDictionary(x => x.Address, x => x.Amount))}");
+ throw;
+ }
+ }
+
public virtual double AdjustShareDifficulty(double difficulty)
{
return difficulty;
