/ Tools / TestNetRewarder / Processor.cs
Processor.cs
 1  using CodexContractsPlugin;
 2  using CodexContractsPlugin.ChainMonitor;
 3  using GethPlugin;
 4  using Logging;
 5  using Utils;
 6  
 7  namespace TestNetRewarder
 8  {
 9      public class Processor : ITimeSegmentHandler
10      {
11          private readonly RequestBuilder builder;
12          private readonly EventsFormatter eventsFormatter;
13          private readonly ChainState chainState;
14          private readonly Configuration config;
15          private readonly BotClient client;
16          private readonly ILog log;
17          private DateTime lastPeriodUpdateUtc;
18  
19          public Processor(Configuration config, BotClient client, IGethNode geth, ICodexContracts contracts, ILog log)
20          {
21              this.config = config;
22              this.client = client;
23              this.log = log;
24              lastPeriodUpdateUtc = DateTime.UtcNow;
25  
26              if (config.ProofReportHours < 1) throw new Exception("ProofReportHours must be one or greater");
27  
28              builder = new RequestBuilder();
29              eventsFormatter = new EventsFormatter(config, contracts.Deployment.Config);
30  
31              chainState = new ChainState(log, geth, contracts, eventsFormatter, config.HistoryStartUtc,
32                  doProofPeriodMonitoring: config.ShowProofPeriodReports > 0, new DoNothingPeriodMonitorEventHandler());
33          }
34  
35          public async Task Initialize()
36          {
37              var events = eventsFormatter.GetInitializationEvents(config);
38              var request = builder.Build(chainState, events, Array.Empty<string>());
39              if (request.HasAny())
40              {
41                  await client.SendRewards(request);
42              }
43          }
44  
45          public async Task<TimeSegmentResponse> OnNewSegment(TimeRange timeRange)
46          {
47              try
48              {
49                  var sw = System.Diagnostics.Stopwatch.StartNew();
50                  var numberOfChainEvents = await ProcessEvents(timeRange);
51                  var duration = sw.Elapsed;
52  
53                  if (duration > TimeSpan.FromSeconds(1)) return TimeSegmentResponse.Underload;
54                  if (duration > TimeSpan.FromSeconds(3)) return TimeSegmentResponse.Overload;
55                  return TimeSegmentResponse.OK;
56              }
57              catch (Exception ex)
58              {
59                  var msg = "Exception processing time segment: " + ex;
60                  log.Error(msg); 
61                  eventsFormatter.OnError(msg);
62                  throw;
63              }
64          }
65  
66          private async Task<int> ProcessEvents(TimeRange timeRange)
67          {
68              var numberOfChainEvents = chainState.Update(timeRange.To);
69              ProcessPeriodUpdate();
70  
71              var events = eventsFormatter.GetEvents();
72              var errors = eventsFormatter.GetErrors();
73  
74              var request = builder.Build(chainState, events, errors);
75              if (request.HasAny())
76              {
77                  await client.SendRewards(request);
78              }
79              return numberOfChainEvents;
80          }
81  
82          private void ProcessPeriodUpdate()
83          {
84              if (config.ShowProofPeriodReports < 1) return;
85              if (DateTime.UtcNow < (lastPeriodUpdateUtc + TimeSpan.FromHours(config.ProofReportHours))) return;
86              lastPeriodUpdateUtc = DateTime.UtcNow;
87  
88              eventsFormatter.ProcessPeriodReports(chainState.PeriodMonitor.GetAndClearReports());
89          }
90      }
91  }