2025-04-24 12:53:08 +02:00
|
|
|
|
using CodexContractsPlugin;
|
|
|
|
|
|
using CodexContractsPlugin.ChainMonitor;
|
|
|
|
|
|
using Logging;
|
2025-08-12 15:23:12 +02:00
|
|
|
|
using Utils;
|
2025-04-24 12:53:08 +02:00
|
|
|
|
|
2025-05-30 08:59:43 +02:00
|
|
|
|
namespace CodexReleaseTests.Utils
|
2025-04-24 12:53:08 +02:00
|
|
|
|
{
|
|
|
|
|
|
public class ChainMonitor
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ILog log;
|
|
|
|
|
|
private readonly ICodexContracts contracts;
|
|
|
|
|
|
private readonly DateTime startUtc;
|
|
|
|
|
|
private readonly TimeSpan updateInterval;
|
|
|
|
|
|
private CancellationTokenSource cts = new CancellationTokenSource();
|
|
|
|
|
|
private Task worker = Task.CompletedTask;
|
|
|
|
|
|
|
|
|
|
|
|
public ChainMonitor(ILog log, ICodexContracts contracts, DateTime startUtc)
|
|
|
|
|
|
: this(log, contracts, startUtc, TimeSpan.FromSeconds(3.0))
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ChainMonitor(ILog log, ICodexContracts contracts, DateTime startUtc, TimeSpan updateInterval)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.log = log;
|
|
|
|
|
|
this.contracts = contracts;
|
|
|
|
|
|
this.startUtc = startUtc;
|
|
|
|
|
|
this.updateInterval = updateInterval;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-27 12:10:45 +02:00
|
|
|
|
public void Start(Action onFailure)
|
2025-04-24 12:53:08 +02:00
|
|
|
|
{
|
|
|
|
|
|
cts = new CancellationTokenSource();
|
2025-04-27 12:10:45 +02:00
|
|
|
|
worker = Task.Run(() => Worker(onFailure));
|
2025-04-24 12:53:08 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Stop()
|
|
|
|
|
|
{
|
|
|
|
|
|
cts.Cancel();
|
|
|
|
|
|
worker.Wait();
|
|
|
|
|
|
if (worker.Exception != null) throw worker.Exception;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-27 12:10:45 +02:00
|
|
|
|
private void Worker(Action onFailure)
|
2025-04-24 12:53:08 +02:00
|
|
|
|
{
|
2025-07-07 15:53:26 +02:00
|
|
|
|
var state = new ChainState(log, contracts, new DoNothingThrowingChainEventHandler(), startUtc, doProofPeriodMonitoring: true);
|
2025-04-24 12:53:08 +02:00
|
|
|
|
Thread.Sleep(updateInterval);
|
|
|
|
|
|
|
2025-08-12 15:23:12 +02:00
|
|
|
|
log.Log($"Chain monitoring started. Update interval: {Time.FormatDuration(updateInterval)}");
|
2025-04-24 12:53:08 +02:00
|
|
|
|
while (!cts.IsCancellationRequested)
|
|
|
|
|
|
{
|
2025-04-27 12:10:45 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
UpdateChainState(state);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.Error("Exception in chain monitor: " + ex);
|
|
|
|
|
|
onFailure();
|
|
|
|
|
|
throw;
|
|
|
|
|
|
}
|
2025-04-24 12:53:08 +02:00
|
|
|
|
|
|
|
|
|
|
cts.Token.WaitHandle.WaitOne(updateInterval);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateChainState(ChainState state)
|
|
|
|
|
|
{
|
|
|
|
|
|
state.Update();
|
|
|
|
|
|
|
|
|
|
|
|
var reports = state.PeriodMonitor.GetAndClearReports();
|
|
|
|
|
|
if (reports.IsEmpty) return;
|
|
|
|
|
|
|
|
|
|
|
|
var slots = reports.Reports.Sum(r => Convert.ToInt32(r.TotalNumSlots));
|
2025-08-13 13:54:33 +02:00
|
|
|
|
var required = reports.Reports.Sum(r => Convert.ToInt32(r.ProofsRequired.Length));
|
2025-04-27 12:10:45 +02:00
|
|
|
|
var missed = reports.Reports.Sum(r => r.MissedProofs.Length);
|
2025-04-24 12:53:08 +02:00
|
|
|
|
|
|
|
|
|
|
log.Log($"Proof report: Slots={slots} Required={required} Missed={missed}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|