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 }