mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-02 13:33:07 +00:00
132 lines
4.4 KiB
C#
132 lines
4.4 KiB
C#
using CodexContractsPlugin;
|
|
using CodexContractsPlugin.ChainMonitor;
|
|
using CodexContractsPlugin.Marketplace;
|
|
using GethPlugin;
|
|
using Logging;
|
|
using Nethereum.Hex.HexConvertors.Extensions;
|
|
using Nethereum.Model;
|
|
using Utils;
|
|
|
|
namespace TraceContract
|
|
{
|
|
public class ChainTracer
|
|
{
|
|
private readonly ILog log;
|
|
private readonly IGethNode geth;
|
|
private readonly ICodexContracts contracts;
|
|
private readonly Input input;
|
|
private readonly Output output;
|
|
|
|
public ChainTracer(ILog log, IGethNode geth, ICodexContracts contracts, Input input, Output output)
|
|
{
|
|
this.log = log;
|
|
this.geth = geth;
|
|
this.contracts = contracts;
|
|
this.input = input;
|
|
this.output = output;
|
|
}
|
|
|
|
public TimeRange TraceChainTimeline()
|
|
{
|
|
log.Log("Querying blockchain...");
|
|
var request = GetRequest();
|
|
if (request == null) throw new Exception("Failed to find the purchase in the last week of transactions.");
|
|
|
|
var creationEvent = FindRequestCreationEvent();
|
|
|
|
log.Log($"Request started at {creationEvent.Block.Utc}");
|
|
var contractEnd = RunToContractEnd(creationEvent);
|
|
|
|
var requestTimeline = new TimeRange(creationEvent.Block.Utc.AddMinutes(-1.0), contractEnd.AddMinutes(1.0));
|
|
log.Log($"Request timeline: {requestTimeline.From} -> {requestTimeline.To}");
|
|
|
|
// For this timeline, we log all the calls to reserve-slot.
|
|
var events = contracts.GetEvents(requestTimeline);
|
|
|
|
events.GetReserveSlotCalls(call =>
|
|
{
|
|
if (IsThisRequest(call.RequestId))
|
|
{
|
|
output.LogReserveSlotCall(call);
|
|
log.Log("Found reserve-slot call for slotIndex " + call.SlotIndex);
|
|
}
|
|
});
|
|
|
|
log.Log("Writing blockchain output...");
|
|
output.WriteContractEvents();
|
|
|
|
return requestTimeline;
|
|
}
|
|
|
|
private DateTime RunToContractEnd(StorageRequestedEventDTO request)
|
|
{
|
|
var utc = request.Block.Utc.AddMinutes(-1.0);
|
|
var tracker = new ChainRequestTracker(output, input.PurchaseId);
|
|
var ignoreLog = new NullLog();
|
|
var chainState = new ChainState(ignoreLog, geth, contracts, tracker, utc, false);
|
|
|
|
var atNow = false;
|
|
while (!tracker.IsFinished && !atNow)
|
|
{
|
|
utc += TimeSpan.FromHours(1.0);
|
|
if (utc > DateTime.UtcNow)
|
|
{
|
|
log.Log("Caught up to present moment without finding contract end.");
|
|
utc = DateTime.UtcNow;
|
|
atNow = true;
|
|
}
|
|
|
|
log.Log($"Querying up to {utc}");
|
|
chainState.Update(utc);
|
|
}
|
|
|
|
if (atNow) return utc;
|
|
return tracker.FinishUtc;
|
|
}
|
|
|
|
private bool IsThisRequest(byte[] requestId)
|
|
{
|
|
return requestId.ToHex().ToLowerInvariant() == input.PurchaseId.ToLowerInvariant();
|
|
}
|
|
|
|
private Request? GetRequest()
|
|
{
|
|
return contracts.GetRequest(input.RequestId);
|
|
}
|
|
|
|
public StorageRequestedEventDTO FindRequestCreationEvent()
|
|
{
|
|
var range = new TimeRange(DateTime.UtcNow - TimeSpan.FromHours(3.0), DateTime.UtcNow);
|
|
var limit = DateTime.UtcNow - TimeSpan.FromDays(30);
|
|
|
|
while (range.From > limit)
|
|
{
|
|
var events = contracts.GetEvents(range);
|
|
foreach (var r in events.GetStorageRequestedEvents())
|
|
{
|
|
if (r.RequestId.ToHex() == input.RequestId.ToHex()) return r;
|
|
}
|
|
|
|
range = new TimeRange(range.From - TimeSpan.FromHours(3.0), range.From);
|
|
}
|
|
|
|
throw new Exception("Unable to find storage request creation event on-chain after (limit) " + Time.FormatTimestamp(limit));
|
|
}
|
|
|
|
private static TimeRange LastHour()
|
|
{
|
|
return new TimeRange(DateTime.UtcNow.AddHours(-1.0), DateTime.UtcNow);
|
|
}
|
|
|
|
private static TimeRange LastDay()
|
|
{
|
|
return new TimeRange(DateTime.UtcNow.AddDays(-1.0), DateTime.UtcNow);
|
|
}
|
|
|
|
private static TimeRange LastWeek()
|
|
{
|
|
return new TimeRange(DateTime.UtcNow.AddDays(-7.0), DateTime.UtcNow);
|
|
}
|
|
}
|
|
}
|