mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-02 13:33:07 +00:00
138 lines
4.7 KiB
C#
138 lines
4.7 KiB
C#
using CodexContractsPlugin.Marketplace;
|
|
using GethPlugin;
|
|
using Logging;
|
|
using Nethereum.Contracts;
|
|
using Nethereum.Hex.HexConvertors.Extensions;
|
|
using Nethereum.Model;
|
|
using Nethereum.RPC.Eth.DTOs;
|
|
using Newtonsoft.Json;
|
|
using System.Reflection;
|
|
|
|
namespace CodexContractsPlugin.ChainMonitor
|
|
{
|
|
public class PeriodMonitor
|
|
{
|
|
private readonly ILog log;
|
|
private readonly ICodexContracts contracts;
|
|
private readonly IGethNode geth;
|
|
private readonly List<PeriodReport> reports = new List<PeriodReport>();
|
|
private CurrentPeriod? currentPeriod = null;
|
|
|
|
public PeriodMonitor(ILog log, ICodexContracts contracts, IGethNode geth)
|
|
{
|
|
this.log = log;
|
|
this.contracts = contracts;
|
|
this.geth = geth;
|
|
}
|
|
|
|
public void Update(DateTime eventUtc, IChainStateRequest[] requests)
|
|
{
|
|
var periodNumber = contracts.GetPeriodNumber(eventUtc);
|
|
if (currentPeriod == null)
|
|
{
|
|
currentPeriod = CreateCurrentPeriod(periodNumber, requests);
|
|
return;
|
|
}
|
|
if (periodNumber == currentPeriod.PeriodNumber) return;
|
|
|
|
CreateReportForPeriod(currentPeriod, requests);
|
|
currentPeriod = CreateCurrentPeriod(periodNumber, requests);
|
|
}
|
|
|
|
public PeriodMonitorResult GetAndClearReports()
|
|
{
|
|
var result = reports.ToArray();
|
|
reports.Clear();
|
|
return new PeriodMonitorResult(result);
|
|
}
|
|
|
|
private CurrentPeriod CreateCurrentPeriod(ulong periodNumber, IChainStateRequest[] requests)
|
|
{
|
|
var result = new CurrentPeriod(periodNumber);
|
|
ForEachActiveSlot(requests, (request, slotIndex) =>
|
|
{
|
|
if (contracts.IsProofRequired(request.RequestId, slotIndex))
|
|
{
|
|
var idx = Convert.ToInt32(slotIndex);
|
|
var host = request.Hosts.GetHost(idx);
|
|
if (host != null)
|
|
{
|
|
result.RequiredProofs.Add(new PeriodRequiredProof(host, request, idx));
|
|
}
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
private void CreateReportForPeriod(CurrentPeriod currentPeriod, IChainStateRequest[] requests)
|
|
{
|
|
// Fetch function calls during period. Format report.
|
|
var timeRange = contracts.GetPeriodTimeRange(currentPeriod.PeriodNumber);
|
|
var blockRange = geth.ConvertTimeRangeToBlockRange(timeRange);
|
|
|
|
var callReports = new List<FunctionCallReport>();
|
|
geth.IterateTransactions(blockRange, (t, blkI, blkUtc) =>
|
|
{
|
|
CreateFunctionCallReport<MarkProofAsMissingFunction>(callReports, t, blkUtc);
|
|
CreateFunctionCallReport<SubmitProofFunction>(callReports, t, blkUtc);
|
|
CreateFunctionCallReport<FreeSlot1Function>(callReports, t, blkUtc);
|
|
CreateFunctionCallReport<FreeSlotFunction>(callReports, t, blkUtc);
|
|
});
|
|
|
|
var report = new PeriodReport(
|
|
new ProofPeriod(
|
|
currentPeriod.PeriodNumber,
|
|
timeRange.From,
|
|
timeRange.To),
|
|
currentPeriod.RequiredProofs.ToArray(),
|
|
callReports.ToArray());
|
|
|
|
report.Log(log);
|
|
reports.Add(report);
|
|
}
|
|
|
|
private void CreateFunctionCallReport<TFunc>(List<FunctionCallReport> reports, Transaction t, DateTime blockUtc) where TFunc : FunctionMessage, new()
|
|
{
|
|
if (t.IsTransactionForFunctionMessage<TFunc>())
|
|
{
|
|
var func = t.DecodeTransactionToFunctionMessage<TFunc>();
|
|
|
|
reports.Add(new FunctionCallReport(blockUtc, typeof(TFunc).Name, JsonConvert.SerializeObject(func)));
|
|
}
|
|
}
|
|
|
|
private void ForEachActiveSlot(IChainStateRequest[] requests, Action<IChainStateRequest, ulong> action)
|
|
{
|
|
foreach (var request in requests)
|
|
{
|
|
for (ulong slotIndex = 0; slotIndex < request.Request.Ask.Slots; slotIndex++)
|
|
{
|
|
action(request, slotIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public class PeriodMonitorResult
|
|
{
|
|
public PeriodMonitorResult(PeriodReport[] reports)
|
|
{
|
|
Reports = reports;
|
|
}
|
|
|
|
public PeriodReport[] Reports { get; }
|
|
}
|
|
|
|
public class CurrentPeriod
|
|
{
|
|
public CurrentPeriod(ulong periodNumber)
|
|
{
|
|
PeriodNumber = periodNumber;
|
|
}
|
|
|
|
public ulong PeriodNumber { get; }
|
|
public List<PeriodRequiredProof> RequiredProofs { get; } = new List<PeriodRequiredProof>();
|
|
}
|
|
}
|