diff --git a/TestNetRewarder/Checks.cs b/TestNetRewarder/Checks.cs index e82c225..8563cf7 100644 --- a/TestNetRewarder/Checks.cs +++ b/TestNetRewarder/Checks.cs @@ -22,7 +22,7 @@ namespace TestNetRewarder private readonly ByteSize minSize; private readonly TimeSpan minDuration; - public FinishedSlot(ByteSize minSize, TimeSpan minDuration) + public FinishedSlotCheck(ByteSize minSize, TimeSpan minDuration) { this.minSize = minSize; this.minDuration = minDuration; @@ -66,7 +66,7 @@ namespace TestNetRewarder private readonly ByteSize minSlotSize; private readonly TimeSpan minDuration; - public StartedContract(ulong minNumberOfHosts, ByteSize minSlotSize, TimeSpan minDuration) + public StartedContractCheck(ulong minNumberOfHosts, ByteSize minSlotSize, TimeSpan minDuration) { this.minNumberOfHosts = minNumberOfHosts; this.minSlotSize = minSlotSize; diff --git a/TestNetRewarder/Processor.cs b/TestNetRewarder/Processor.cs new file mode 100644 index 0000000..a1418e3 --- /dev/null +++ b/TestNetRewarder/Processor.cs @@ -0,0 +1,74 @@ +using BiblioTech.Rewards; +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(); + private readonly ILog log; + + public Processor(ILog log) + { + this.log = log; + } + + public async Task ProcessTimeSegment(TimeRange range) + { + try + { + var connector = GethConnector.GethConnector.Initialize(log); + if (connector == null) return; + + var chainState = new ChainState(historicState, connector.CodexContracts, range); + await ProcessTimeSegment(chainState); + + } + catch (Exception ex) + { + log.Error("Exception processing time segment: " + ex); + } + } + + private async Task ProcessTimeSegment(ChainState chainState) + { + var outgoingRewards = new List(); + foreach (var reward in rewardRepo.Rewards) + { + ProcessReward(outgoingRewards, reward, chainState); + } + + if (outgoingRewards.Any()) + { + await SendRewardsCommand(outgoingRewards); + } + } + + private async Task SendRewardsCommand(List outgoingRewards) + { + var cmd = new GiveRewardsCommand + { + Rewards = outgoingRewards.ToArray() + }; + + log.Debug("Sending rewards: " + JsonConvert.SerializeObject(cmd)); + await Program.BotClient.SendRewards(cmd); + } + + private void ProcessReward(List outgoingRewards, RewardConfig reward, ChainState chainState) + { + var winningAddresses = reward.Check.Check(chainState); + if (winningAddresses.Any()) + { + outgoingRewards.Add(new RewardUsersCommand + { + RewardId = reward.RewardId, + UserAddresses = winningAddresses.Select(a => a.Address).ToArray() + }); + } + } + } +} diff --git a/TestNetRewarder/Program.cs b/TestNetRewarder/Program.cs index 01945c7..ac248c1 100644 --- a/TestNetRewarder/Program.cs +++ b/TestNetRewarder/Program.cs @@ -1,7 +1,4 @@ using ArgsUniform; -using CodexContractsPlugin.Marketplace; -using CodexContractsPlugin; -using GethPlugin; using Logging; using Utils; @@ -12,6 +9,7 @@ namespace TestNetRewarder public static Configuration Config { get; private set; } = null!; public static ILog Log { get; private set; } = null!; public static CancellationToken CancellationToken { get; private set; } + public static BotClient BotClient { get; private set; } = null!; public static Task Main(string[] args) { @@ -27,6 +25,8 @@ namespace TestNetRewarder new ConsoleLog() ); + BotClient = new BotClient(Config, Log); + EnsurePath(Config.DataPath); EnsurePath(Config.LogPath); @@ -40,35 +40,27 @@ namespace TestNetRewarder while (!CancellationToken.IsCancellationRequested) { + await EnsureBotOnline(); await segmenter.WaitForNextSegment(ProcessTimeSegment); await Task.Delay(1000, CancellationToken); } } - private async Task ProcessTimeSegment(TimeRange range) + private async Task EnsureBotOnline() { - try + var start = DateTime.UtcNow; + while (! await BotClient.IsOnline() && !CancellationToken.IsCancellationRequested) { - var connector = GethConnector.GethConnector.Initialize(Log); - if (connector == null) return; - - //Request[] GetStorageRequests(TimeRange timeRange); - //EthAddress GetSlotHost(Request storageRequest, decimal slotIndex); - //RequestState GetRequestState(Request request); - //RequestFulfilledEventDTO[] GetRequestFulfilledEvents(TimeRange timeRange); - //RequestCancelledEventDTO[] GetRequestCancelledEvents(TimeRange timeRange); - //SlotFilledEventDTO[] GetSlotFilledEvents(TimeRange timeRange); - //SlotFreedEventDTO[] GetSlotFreedEvents(TimeRange timeRange); - - + await Task.Delay(5000); + var elapsed = DateTime.UtcNow - start; + if (elapsed.TotalMinutes > 10) + { + var msg = "Unable to connect to bot for " + Time.FormatDuration(elapsed); + Log.Error(msg); + throw new Exception(msg); + } } - catch (Exception ex) - { - Log.Error("Exception processing time segment: " + ex); - } - - await Task.Delay(1); } private static void PrintHelp() diff --git a/TestNetRewarder/RewardConfig.cs b/TestNetRewarder/RewardConfig.cs new file mode 100644 index 0000000..9906359 --- /dev/null +++ b/TestNetRewarder/RewardConfig.cs @@ -0,0 +1,50 @@ +using Utils; + +namespace TestNetRewarder +{ + public class RewardConfig + { + public RewardConfig(ulong rewardId, ICheck check) + { + RewardId = rewardId; + Check = check; + } + + public ulong RewardId { get; } + public ICheck Check { get; } + } + + public class RewardRepo + { + public RewardConfig[] Rewards { get; } = new RewardConfig[] + { + // Filled any slot + new RewardConfig(123, new FilledAnySlotCheck()), + + // Finished any slot + new RewardConfig(124, new FinishedSlotCheck( + minSize: 0.Bytes(), + minDuration: TimeSpan.Zero)), + + // Finished a sizable slot + new RewardConfig(125, new FinishedSlotCheck( + minSize: 1.GB(), + minDuration: TimeSpan.FromHours(24.0))), + + // Posted any contract + new RewardConfig(126, new PostedContractCheck()), + + // Started any contract + new RewardConfig(127, new StartedContractCheck( + minNumberOfHosts: 1, + minSlotSize: 0.Bytes(), + minDuration: TimeSpan.Zero)), + + // Started a sizable contract + new RewardConfig(127, new StartedContractCheck( + minNumberOfHosts: 4, + minSlotSize: 1.GB(), + minDuration: TimeSpan.FromHours(24.0))) + }; + } +}