mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-02 13:33:07 +00:00
Setting up contract tracer
This commit is contained in:
parent
0e66e8e94a
commit
a85caae203
@ -4,8 +4,6 @@ using GethPlugin;
|
||||
using Logging;
|
||||
using Nethereum.Contracts;
|
||||
using Nethereum.Hex.HexTypes;
|
||||
using Nethereum.RPC.Eth.DTOs;
|
||||
using Nethereum.Web3;
|
||||
using Utils;
|
||||
|
||||
namespace CodexContractsPlugin
|
||||
@ -105,7 +103,11 @@ namespace CodexContractsPlugin
|
||||
public ReserveSlotFunction[] GetReserveSlotCalls()
|
||||
{
|
||||
var result = new List<ReserveSlotFunction>();
|
||||
gethNode.IterateFunctionCalls<ReserveSlotFunction>(BlockInterval, result.Add);
|
||||
gethNode.IterateFunctionCalls<ReserveSlotFunction>(BlockInterval, (b, fn) =>
|
||||
{
|
||||
fn.Block = b;
|
||||
result.Add(fn);
|
||||
});
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,11 @@ namespace CodexContractsPlugin.Marketplace
|
||||
byte[] RequestId { get; set; }
|
||||
}
|
||||
|
||||
public interface IHasSlotIndex
|
||||
{
|
||||
ulong SlotIndex { get; set; }
|
||||
}
|
||||
|
||||
public partial class Request : RequestBase, IHasBlock, IHasRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
@ -51,20 +56,20 @@ namespace CodexContractsPlugin.Marketplace
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class SlotFilledEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
public EthAddress Host { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFreedEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class SlotFreedEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
@ -75,5 +80,11 @@ namespace CodexContractsPlugin.Marketplace
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class ReserveSlotFunction : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
@ -31,7 +31,7 @@ namespace GethPlugin
|
||||
List<EventLog<TEvent>> GetEvents<TEvent>(string address, TimeRange timeRange) where TEvent : IEventDTO, new();
|
||||
BlockInterval ConvertTimeRangeToBlockRange(TimeRange timeRange);
|
||||
BlockTimeEntry GetBlockForNumber(ulong number);
|
||||
void IterateFunctionCalls<TFunc>(BlockInterval blockInterval, Action<TFunc> onCall) where TFunc : FunctionMessage, new();
|
||||
void IterateFunctionCalls<TFunc>(BlockInterval blockInterval, Action<BlockTimeEntry, TFunc> onCall) where TFunc : FunctionMessage, new();
|
||||
}
|
||||
|
||||
public class DeploymentGethNode : BaseGethNode, IGethNode
|
||||
@ -189,7 +189,7 @@ namespace GethPlugin
|
||||
return StartInteraction().GetBlockWithTransactions(number);
|
||||
}
|
||||
|
||||
public void IterateFunctionCalls<TFunc>(BlockInterval blockRange, Action<TFunc> onCall) where TFunc : FunctionMessage, new()
|
||||
public void IterateFunctionCalls<TFunc>(BlockInterval blockRange, Action<BlockTimeEntry, TFunc> onCall) where TFunc : FunctionMessage, new()
|
||||
{
|
||||
var i = StartInteraction();
|
||||
for (var blkI = blockRange.From; blkI <= blockRange.To; blkI++)
|
||||
@ -201,7 +201,11 @@ namespace GethPlugin
|
||||
if (t.IsTransactionForFunctionMessage<TFunc>())
|
||||
{
|
||||
var func = t.DecodeTransactionToFunctionMessage<TFunc>();
|
||||
if (func != null) onCall(func);
|
||||
if (func != null)
|
||||
{
|
||||
var b = GetBlockForNumber(blkI);
|
||||
onCall(b, func);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ namespace CodexReleaseTests.MarketTests
|
||||
Log($"Request '{requestId}' failed to start. There were {calls.Length} hosts who called reserve-slot for it:");
|
||||
foreach (var c in calls)
|
||||
{
|
||||
Log($" - Host: {c.FromAddress} RequestId: {c.RequestId.ToHex()} SlotIndex: {c.SlotIndex}");
|
||||
Log($" - {c.Block.Utc} Host: {c.FromAddress} RequestId: {c.RequestId.ToHex()} SlotIndex: {c.SlotIndex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
TraceContract/Config.cs
Normal file
11
TraceContract/Config.cs
Normal file
File diff suppressed because one or more lines are too long
18
TraceContract/Output.cs
Normal file
18
TraceContract/Output.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using CodexContractsPlugin;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
|
||||
namespace TraceContract
|
||||
{
|
||||
public class Output
|
||||
{
|
||||
public void LogRequest(Request request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void LogEventOrCall<T>(T[] calls) where T : IHasRequestId, IHasBlock
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
169
TraceContract/Program.cs
Normal file
169
TraceContract/Program.cs
Normal file
@ -0,0 +1,169 @@
|
||||
using BlockchainUtils;
|
||||
using CodexContractsPlugin;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using Core;
|
||||
using GethPlugin;
|
||||
using Logging;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using Utils;
|
||||
|
||||
namespace TraceContract
|
||||
{
|
||||
public class Input
|
||||
{
|
||||
public string PurchaseId { get; } = "a7fe97dc32216aba0cbe74b87beb3f919aa116090dd5e0d48085a1a6b0080e82";
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var p = new Program();
|
||||
p.Run();
|
||||
}
|
||||
|
||||
private readonly ILog log = new ConsoleLog();
|
||||
private readonly Input input = new();
|
||||
private readonly Output output = new();
|
||||
private readonly Config config = new();
|
||||
|
||||
private void Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
TracePurchase();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.Error(exc.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void TracePurchase()
|
||||
{
|
||||
Log("Setting up...");
|
||||
var contracts = ConnectCodexContracts();
|
||||
|
||||
var chainTracer = new ChainTracer(log, contracts, input, output);
|
||||
chainTracer.TraceChainTimeline();
|
||||
|
||||
Log("Done");
|
||||
}
|
||||
|
||||
private ICodexContracts ConnectCodexContracts()
|
||||
{
|
||||
ProjectPlugin.Load<GethPlugin.GethPlugin>();
|
||||
ProjectPlugin.Load<CodexContractsPlugin.CodexContractsPlugin>();
|
||||
|
||||
var entryPoint = new EntryPoint(log, new KubernetesWorkflow.Configuration(null, TimeSpan.FromMinutes(1.0), TimeSpan.FromSeconds(10.0), "_Unused!_"), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
|
||||
entryPoint.Announce();
|
||||
var ci = entryPoint.CreateInterface();
|
||||
|
||||
var account = EthAccountGenerator.GenerateNew();
|
||||
var blockCache = new BlockCache();
|
||||
var geth = new CustomGethNode(log, blockCache, config.RpcEndpoint, config.GethPort, account.PrivateKey);
|
||||
|
||||
var deployment = new CodexContractsDeployment(
|
||||
config: new CodexContractsPlugin.Marketplace.MarketplaceConfig(),
|
||||
marketplaceAddress: config.MarketplaceAddress,
|
||||
abi: config.Abi,
|
||||
tokenAddress: config.TokenAddress
|
||||
);
|
||||
return ci.WrapCodexContractsDeployment(geth, deployment);
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
{
|
||||
log.Log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public class ChainTracer
|
||||
{
|
||||
private readonly ILog log;
|
||||
private readonly ICodexContracts contracts;
|
||||
private readonly Input input;
|
||||
private readonly Output output;
|
||||
|
||||
public ChainTracer(ILog log, ICodexContracts contracts, Input input, Output output)
|
||||
{
|
||||
this.log = log;
|
||||
this.contracts = contracts;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public void TraceChainTimeline()
|
||||
{
|
||||
var request = GetRequest();
|
||||
if (request == null) throw new Exception("Failed to find the purchase in the last week of transactions.");
|
||||
output.LogRequest(request);
|
||||
|
||||
var requestTimeRange = new TimeRange(request.Block.Utc.AddMinutes(-1.0), DateTime.UtcNow);
|
||||
var events = contracts.GetEvents(requestTimeRange);
|
||||
|
||||
// Log calls to reserve slot for request
|
||||
var calls = Filter(events.GetReserveSlotCalls());
|
||||
output.LogEventOrCall(calls);
|
||||
|
||||
// log all events.
|
||||
var fulls = events.GetSlotReservationsFullEvents();
|
||||
output.LogEventOrCall(Filter(fulls));
|
||||
|
||||
}
|
||||
|
||||
private T[] Filter<T>(T[] calls) where T : IHasRequestId
|
||||
{
|
||||
return calls.Where(c => IsThisRequest(c.RequestId)).ToArray();
|
||||
}
|
||||
|
||||
private Request? GetRequest()
|
||||
{
|
||||
var request = FindRequest(LastHour());
|
||||
if (request == null) request = FindRequest(LastDay());
|
||||
if (request == null) request = FindRequest(LastWeek());
|
||||
return request;
|
||||
}
|
||||
|
||||
private Request? FindRequest(TimeRange timeRange)
|
||||
{
|
||||
var events = contracts.GetEvents(timeRange);
|
||||
var requests = events.GetStorageRequests();
|
||||
|
||||
foreach (var r in requests)
|
||||
{
|
||||
if (IsThisRequest(r.RequestId))
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsThisRequest(byte[] requestId)
|
||||
{
|
||||
return requestId.ToHex().ToLowerInvariant() == input.PurchaseId.ToLowerInvariant();
|
||||
}
|
||||
|
||||
private TimeRange LastHour()
|
||||
{
|
||||
return new TimeRange(DateTime.UtcNow.AddHours(-1.0), DateTime.UtcNow);
|
||||
}
|
||||
|
||||
private TimeRange LastDay()
|
||||
{
|
||||
return new TimeRange(DateTime.UtcNow.AddDays(-1.0), DateTime.UtcNow);
|
||||
}
|
||||
|
||||
private TimeRange LastWeek()
|
||||
{
|
||||
return new TimeRange(DateTime.UtcNow.AddDays(-7.0), DateTime.UtcNow);
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
{
|
||||
log.Log(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
TraceContract/TraceContract.csproj
Normal file
16
TraceContract/TraceContract.csproj
Normal file
@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Framework\Logging\Logging.csproj" />
|
||||
<ProjectReference Include="..\ProjectPlugins\CodexContractsPlugin\CodexContractsPlugin.csproj" />
|
||||
<ProjectReference Include="..\ProjectPlugins\GethPlugin\GethPlugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -86,6 +86,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodexClient", "ProjectPlugi
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebUtils", "Framework\WebUtils\WebUtils.csproj", "{372C9E5D-5453-4D45-9948-E9324E21AD65}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TraceContract", "TraceContract\TraceContract.csproj", "{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -232,6 +234,10 @@ Global
|
||||
{372C9E5D-5453-4D45-9948-E9324E21AD65}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{372C9E5D-5453-4D45-9948-E9324E21AD65}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{372C9E5D-5453-4D45-9948-E9324E21AD65}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -272,6 +278,7 @@ Global
|
||||
{4648B5AA-A0A7-44BA-89BC-2FD57370943C} = {81AE04BC-CBFA-4E6F-B039-8208E9AFAAE7}
|
||||
{9AF12703-29AF-416D-9781-204223D6D0E5} = {8F1F1C2A-E313-4E0C-BE40-58FB0BA91124}
|
||||
{372C9E5D-5453-4D45-9948-E9324E21AD65} = {81AE04BC-CBFA-4E6F-B039-8208E9AFAAE7}
|
||||
{6F4C72D7-4B6E-45FD-93C6-2099CBE5B2AC} = {7591C5B3-D86E-4AE4-8ED2-B272D17FE7E3}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user