2
0
mirror of synced 2025-02-13 08:56:30 +00:00

145 lines
5.0 KiB
C#
Raw Normal View History

using DiscordRewards;
using GethPlugin;
2024-01-26 18:17:56 -05:00
using Logging;
using Newtonsoft.Json;
using Utils;
namespace TestNetRewarder
{
public class Processor
{
private static readonly HistoricState historicState = new HistoricState();
private static readonly RewardRepo rewardRepo = new RewardRepo();
2024-04-07 14:04:31 +02:00
private static readonly MarketTracker marketTracker = new MarketTracker();
2024-01-26 18:17:56 -05:00
private readonly ILog log;
2024-03-27 15:39:42 +01:00
private BlockInterval? lastBlockRange;
2024-01-26 18:17:56 -05:00
public Processor(ILog log)
{
this.log = log;
}
2024-02-19 15:41:48 +01:00
public async Task ProcessTimeSegment(TimeRange timeRange)
2024-01-26 18:17:56 -05:00
{
2024-04-01 13:56:07 +02:00
var connector = GethConnector.GethConnector.Initialize(log);
if (connector == null) throw new Exception("Invalid Geth information");
2024-01-26 18:17:56 -05:00
try
{
2024-02-19 15:41:48 +01:00
var blockRange = connector.GethNode.ConvertTimeRangeToBlockRange(timeRange);
if (!IsNewBlockRange(blockRange))
{
log.Log($"Block range {blockRange} was previously processed. Skipping...");
return;
}
var chainState = new ChainState(historicState, connector.CodexContracts, blockRange);
2024-04-01 13:56:07 +02:00
await ProcessChainState(chainState);
2024-01-26 18:17:56 -05:00
}
catch (Exception ex)
{
log.Error("Exception processing time segment: " + ex);
2024-04-01 13:56:07 +02:00
throw;
2024-01-26 18:17:56 -05:00
}
}
2024-03-27 15:39:42 +01:00
private bool IsNewBlockRange(BlockInterval blockRange)
2024-02-19 15:41:48 +01:00
{
if (lastBlockRange == null ||
lastBlockRange.From != blockRange.From ||
lastBlockRange.To != blockRange.To)
{
lastBlockRange = blockRange;
return true;
}
return false;
}
2024-04-01 13:56:07 +02:00
private async Task ProcessChainState(ChainState chainState)
2024-01-26 18:17:56 -05:00
{
var outgoingRewards = new List<RewardUsersCommand>();
foreach (var reward in rewardRepo.Rewards)
{
ProcessReward(outgoingRewards, reward, chainState);
}
2024-04-07 14:04:31 +02:00
var marketAverages = GetMarketAverages(chainState);
var eventsOverview = GenerateEventsOverview(chainState);
2024-04-07 14:04:31 +02:00
log.Log($"Found {outgoingRewards.Count} rewards to send. Found {marketAverages.Length} market averages.");
2024-01-26 18:17:56 -05:00
if (outgoingRewards.Any())
{
if (!await SendRewardsCommand(outgoingRewards, marketAverages, eventsOverview))
2024-02-19 14:56:49 +01:00
{
log.Error("Failed to send reward command.");
}
2024-01-26 18:17:56 -05:00
}
}
private string[] GenerateEventsOverview(ChainState chainState)
{
return chainState.GenerateOverview();
}
2024-04-07 14:04:31 +02:00
private MarketAverage[] GetMarketAverages(ChainState chainState)
{
return marketTracker.ProcessChainState(chainState);
}
private async Task<bool> SendRewardsCommand(List<RewardUsersCommand> outgoingRewards, MarketAverage[] marketAverages, string[] eventsOverview)
2024-01-26 18:17:56 -05:00
{
var cmd = new GiveRewardsCommand
{
2024-04-07 14:04:31 +02:00
Rewards = outgoingRewards.ToArray(),
Averages = marketAverages.ToArray(),
EventsOverview = eventsOverview
2024-01-26 18:17:56 -05:00
};
2024-04-01 13:56:07 +02:00
log.Debug("Sending rewards: " + JsonConvert.SerializeObject(cmd));
2024-02-19 14:56:49 +01:00
return await Program.BotClient.SendRewards(cmd);
2024-01-26 18:17:56 -05:00
}
private void ProcessReward(List<RewardUsersCommand> outgoingRewards, RewardConfig reward, ChainState chainState)
{
var winningAddresses = PerformCheck(reward, chainState);
2024-02-19 15:41:48 +01:00
foreach (var win in winningAddresses)
{
log.Log($"Address '{win.Address}' wins '{reward.Message}'");
}
2024-01-26 18:17:56 -05:00
if (winningAddresses.Any())
{
outgoingRewards.Add(new RewardUsersCommand
{
RewardId = reward.RoleId,
2024-01-26 18:17:56 -05:00
UserAddresses = winningAddresses.Select(a => a.Address).ToArray()
});
}
}
private EthAddress[] PerformCheck(RewardConfig reward, ChainState chainState)
{
var check = GetCheck(reward.CheckConfig);
return check.Check(chainState).Distinct().ToArray();
}
private ICheck GetCheck(CheckConfig config)
{
switch (config.Type)
{
case CheckType.FilledSlot:
return new FilledAnySlotCheck();
case CheckType.FinishedSlot:
return new FinishedSlotCheck(config.MinSlotSize, config.MinDuration);
case CheckType.PostedContract:
return new PostedContractCheck(config.MinNumberOfHosts, config.MinSlotSize, config.MinDuration);
case CheckType.StartedContract:
return new StartedContractCheck(config.MinNumberOfHosts, config.MinSlotSize, config.MinDuration);
}
throw new Exception("Unknown check type: " + config.Type);
}
2024-01-26 18:17:56 -05:00
}
}