From db4c4a87e067cb48a5deffb90644b7e2afac1c99 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 30 Sep 2024 15:34:40 +0200 Subject: [PATCH] Rewarderbot: Speeds up time segments when catching up to realtime. --- .../ChainMonitor/ChainState.cs | 7 +-- Tools/MarketInsights/AverageHistory.cs | 4 +- Tools/TestNetRewarder/Processor.cs | 31 +++++++++---- Tools/TestNetRewarder/TimeSegmenter.cs | 43 +++++++++++++++++-- 4 files changed, 67 insertions(+), 18 deletions(-) diff --git a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs index fba622bf..5244e193 100644 --- a/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs +++ b/ProjectPlugins/CodexContractsPlugin/ChainMonitor/ChainState.cs @@ -48,18 +48,19 @@ namespace CodexContractsPlugin.ChainMonitor public TimeRange TotalSpan { get; private set; } public IChainStateRequest[] Requests => requests.ToArray(); - public void Update() + public int Update() { - Update(DateTime.UtcNow); + return Update(DateTime.UtcNow); } - public void Update(DateTime toUtc) + public int Update(DateTime toUtc) { var span = new TimeRange(TotalSpan.To, toUtc); var events = ChainEvents.FromTimeRange(contracts, span); Apply(events); TotalSpan = new TimeRange(TotalSpan.From, span.To); + return events.All.Length; } private void Apply(ChainEvents events) diff --git a/Tools/MarketInsights/AverageHistory.cs b/Tools/MarketInsights/AverageHistory.cs index 007a35f8..af752d1b 100644 --- a/Tools/MarketInsights/AverageHistory.cs +++ b/Tools/MarketInsights/AverageHistory.cs @@ -23,7 +23,7 @@ namespace MarketInsights public MarketTimeSegment[] Segments { get; private set; } = Array.Empty(); - public Task OnNewSegment(TimeRange timeRange) + public Task OnNewSegment(TimeRange timeRange) { var contribution = BuildContribution(timeRange); contributions.Add(contribution); @@ -35,7 +35,7 @@ namespace MarketInsights Segments = contributions.ToArray(); - return Task.CompletedTask; + return Task.FromResult(TimeSegmentResponse.OK); } private MarketTimeSegment BuildContribution(TimeRange timeRange) diff --git a/Tools/TestNetRewarder/Processor.cs b/Tools/TestNetRewarder/Processor.cs index d16075cc..a6d2ccdf 100644 --- a/Tools/TestNetRewarder/Processor.cs +++ b/Tools/TestNetRewarder/Processor.cs @@ -31,19 +31,18 @@ namespace TestNetRewarder chainState = new ChainState(log, contracts, handler, config.HistoryStartUtc); } - public async Task OnNewSegment(TimeRange timeRange) + public async Task OnNewSegment(TimeRange timeRange) { try { - chainState.Update(timeRange.To); + var sw = System.Diagnostics.Stopwatch.StartNew(); + var numberOfChainEvents = await ProcessEvents(timeRange); + var duration = sw.Elapsed; - var events = eventsFormatter.GetEvents(); - - var request = builder.Build(events); - if (request.HasAny()) - { - await client.SendRewards(request); - } + if (numberOfChainEvents == 0) return TimeSegmentResponse.Underload; + if (numberOfChainEvents > 10) return TimeSegmentResponse.Overload; + if (duration > TimeSpan.FromSeconds(1)) return TimeSegmentResponse.Overload; + return TimeSegmentResponse.OK; } catch (Exception ex) { @@ -53,5 +52,19 @@ namespace TestNetRewarder throw; } } + + private async Task ProcessEvents(TimeRange timeRange) + { + var numberOfChainEvents = chainState.Update(timeRange.To); + + var events = eventsFormatter.GetEvents(); + + var request = builder.Build(events); + if (request.HasAny()) + { + await client.SendRewards(request); + } + return numberOfChainEvents; + } } } diff --git a/Tools/TestNetRewarder/TimeSegmenter.cs b/Tools/TestNetRewarder/TimeSegmenter.cs index 39a9bbb9..5b95603d 100644 --- a/Tools/TestNetRewarder/TimeSegmenter.cs +++ b/Tools/TestNetRewarder/TimeSegmenter.cs @@ -5,15 +5,24 @@ namespace TestNetRewarder { public interface ITimeSegmentHandler { - Task OnNewSegment(TimeRange timeRange); + Task OnNewSegment(TimeRange timeRange); + } + + public enum TimeSegmentResponse + { + OK, + Underload, + Overload } public class TimeSegmenter { + private const int maxSegmentMult = 50; private readonly ILog log; private readonly ITimeSegmentHandler handler; private readonly TimeSpan segmentSize; private DateTime latest; + private int currentSegmentMult = 1; public TimeSegmenter(ILog log, TimeSpan segmentSize, DateTime historyStartUtc, ITimeSegmentHandler handler) { @@ -30,19 +39,45 @@ namespace TestNetRewarder public async Task ProcessNextSegment() { - var end = latest + segmentSize; + var end = GetNewSegmentEnd(); IsRealtime = await WaitUntilTimeSegmentInPast(end); if (Program.CancellationToken.IsCancellationRequested) return; var postfix = "(Catching up...)"; if (IsRealtime) postfix = "(Real-time)"; - log.Log($"Time segment [{latest} to {end}] {postfix}"); + log.Log($"Time segment [{latest} to {end}] {postfix}({currentSegmentMult}x)"); var range = new TimeRange(latest, end); latest = end; - await handler.OnNewSegment(range); + var response = await handler.OnNewSegment(range); + HandleResponse(response); + } + + private DateTime GetNewSegmentEnd() + { + if (IsRealtime) return latest + segmentSize; + var segment = segmentSize * currentSegmentMult; + return latest + segment; + } + + private void HandleResponse(TimeSegmentResponse response) + { + switch (response) + { + case TimeSegmentResponse.OK: + if (currentSegmentMult > 1) currentSegmentMult--; + break; + case TimeSegmentResponse.Underload: + if (currentSegmentMult < maxSegmentMult) currentSegmentMult++; + break; + case TimeSegmentResponse.Overload: + currentSegmentMult = 1; + break; + default: + throw new Exception("Unknown response type: " + response); + } } private async Task WaitUntilTimeSegmentInPast(DateTime end)