From 4a151880d4e636e93cfe643c73ba9a112f9d0d10 Mon Sep 17 00:00:00 2001 From: ThatBen Date: Thu, 16 Jan 2025 11:31:50 +0100 Subject: [PATCH] Extracts codexClient assembly --- Framework/Core/Core.csproj | 1 + Framework/Core/EntryPoint.cs | 7 +- Framework/Core/PluginTools.cs | 31 ++++--- Framework/Core/ToolsFactory.cs | 11 ++- Framework/KubernetesWorkflow/K8sTimeSet.cs | 42 ++++++++++ Framework/Utils/EthAccount.cs | 20 +++++ .../Utils}/EthAddress.cs | 2 +- .../Utils}/EthTokenExtensions.cs | 2 +- .../Utils}/TestTokenExtensions.cs | 2 +- Framework/{Core => WebUtils}/Endpoint.cs | 11 ++- Framework/{Core => WebUtils}/Http.cs | 8 +- Framework/WebUtils/HttpFactory.cs | 43 ++++++++++ .../TimeSet.cs => WebUtils/WebCallTimeSet.cs} | 39 +-------- Framework/WebUtils/WebUtils.csproj | 18 ++++ .../CodexAccess.cs | 84 ++++--------------- ProjectPlugins/CodexClient/CodexClient.csproj | 39 +++++++++ ProjectPlugins/CodexClient/CodexInstance.cs | 40 +++++++++ .../CodexLogLevel.cs | 2 +- .../CodexLogLine.cs | 2 +- .../{CodexPlugin => CodexClient}/CodexNode.cs | 57 +++++-------- .../CodexTypes.cs | 2 +- .../CodexUtils.cs | 2 +- .../Hooks/CodexHooksFactory.cs | 5 +- .../Hooks/CodexNodeHooks.cs | 5 +- .../{CodexPlugin => CodexClient}/Mapper.cs | 20 ++--- .../MarketplaceAccess.cs | 4 +- .../MarketplaceTypes.cs | 5 +- ProjectPlugins/CodexClient/ProcessControl.cs | 11 +++ .../StoragePurchaseContract.cs | 17 +--- .../TransferSpeeds.cs | 2 +- .../{CodexPlugin => CodexClient}/openapi.yaml | 0 ....cs => CodexInstanceContainerExtension.cs} | 37 -------- ProjectPlugins/CodexPlugin/CodexPlugin.csproj | 11 +-- ProjectPlugins/CodexPlugin/CodexStarter.cs | 1 - .../CodexNodeTranscriptWriter.cs | 1 - ProjectPlugins/CodexPlugin/ProcessControl.cs | 29 ------- ProjectPlugins/CodexPluginPrebuild/Program.cs | 18 ++-- .../{EthAccount.cs => EthAccountGenerator.cs} | 18 +--- .../MarketTests/ContractSuccessfulTest.cs | 3 +- .../MarketTests/MultipleContractsTest.cs | 11 ++- .../BasicTests/ExampleTests.cs | 1 - .../BasicTests/MarketplaceTests.cs | 11 ++- .../UtilityTests/DiscordBotTests.cs | 12 ++- Tools/KeyMaker/Controllers/KeyController.cs | 2 +- cs-codex-dist-testing.sln | 14 ++++ 45 files changed, 383 insertions(+), 320 deletions(-) create mode 100644 Framework/KubernetesWorkflow/K8sTimeSet.cs create mode 100644 Framework/Utils/EthAccount.cs rename {ProjectPlugins/GethPlugin => Framework/Utils}/EthAddress.cs (96%) rename {ProjectPlugins/GethPlugin => Framework/Utils}/EthTokenExtensions.cs (98%) rename {ProjectPlugins/CodexContractsPlugin => Framework/Utils}/TestTokenExtensions.cs (98%) rename Framework/{Core => WebUtils}/Endpoint.cs (97%) rename Framework/{Core => WebUtils}/Http.cs (91%) create mode 100644 Framework/WebUtils/HttpFactory.cs rename Framework/{Core/TimeSet.cs => WebUtils/WebCallTimeSet.cs} (55%) create mode 100644 Framework/WebUtils/WebUtils.csproj rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexAccess.cs (73%) create mode 100644 ProjectPlugins/CodexClient/CodexClient.csproj create mode 100644 ProjectPlugins/CodexClient/CodexInstance.cs rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexLogLevel.cs (82%) rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexLogLine.cs (99%) rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexNode.cs (87%) rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexTypes.cs (99%) rename ProjectPlugins/{CodexPlugin => CodexClient}/CodexUtils.cs (95%) rename ProjectPlugins/{CodexPlugin => CodexClient}/Hooks/CodexHooksFactory.cs (96%) rename ProjectPlugins/{CodexPlugin => CodexClient}/Hooks/CodexNodeHooks.cs (91%) rename ProjectPlugins/{CodexPlugin => CodexClient}/Mapper.cs (94%) rename ProjectPlugins/{CodexPlugin => CodexClient}/MarketplaceAccess.cs (98%) rename ProjectPlugins/{CodexPlugin => CodexClient}/MarketplaceTypes.cs (98%) create mode 100644 ProjectPlugins/CodexClient/ProcessControl.cs rename ProjectPlugins/{CodexPlugin => CodexClient}/StoragePurchaseContract.cs (92%) rename ProjectPlugins/{CodexPlugin => CodexClient}/TransferSpeeds.cs (98%) rename ProjectPlugins/{CodexPlugin => CodexClient}/openapi.yaml (100%) rename ProjectPlugins/CodexPlugin/{CodexInstance.cs => CodexInstanceContainerExtension.cs} (54%) delete mode 100644 ProjectPlugins/CodexPlugin/ProcessControl.cs rename ProjectPlugins/GethPlugin/{EthAccount.cs => EthAccountGenerator.cs} (55%) diff --git a/Framework/Core/Core.csproj b/Framework/Core/Core.csproj index 42f1c7a6..b961cd63 100644 --- a/Framework/Core/Core.csproj +++ b/Framework/Core/Core.csproj @@ -9,6 +9,7 @@ + diff --git a/Framework/Core/EntryPoint.cs b/Framework/Core/EntryPoint.cs index 0db40f3d..558d2870 100644 --- a/Framework/Core/EntryPoint.cs +++ b/Framework/Core/EntryPoint.cs @@ -1,5 +1,6 @@ using KubernetesWorkflow; using Logging; +using WebUtils; namespace Core { @@ -8,16 +9,16 @@ namespace Core private readonly IToolsFactory toolsFactory; private readonly PluginManager manager = new PluginManager(); - public EntryPoint(ILog log, Configuration configuration, string fileManagerRootFolder, ITimeSet timeSet) + public EntryPoint(ILog log, Configuration configuration, string fileManagerRootFolder, IWebCallTimeSet webCallTimeSet, IK8sTimeSet k8STimeSet) { - toolsFactory = new ToolsFactory(log, configuration, fileManagerRootFolder, timeSet); + toolsFactory = new ToolsFactory(log, configuration, fileManagerRootFolder, webCallTimeSet, k8STimeSet); Tools = toolsFactory.CreateTools(); manager.InstantiatePlugins(PluginFinder.GetPluginTypes(), toolsFactory); } public EntryPoint(ILog log, Configuration configuration, string fileManagerRootFolder) - : this(log, configuration, fileManagerRootFolder, new DefaultTimeSet()) + : this(log, configuration, fileManagerRootFolder, new DefaultWebCallTimeSet(), new DefaultK8sTimeSet()) { } diff --git a/Framework/Core/PluginTools.cs b/Framework/Core/PluginTools.cs index 3db27449..e6eb18a6 100644 --- a/Framework/Core/PluginTools.cs +++ b/Framework/Core/PluginTools.cs @@ -1,12 +1,14 @@ using FileUtils; using KubernetesWorkflow; using Logging; +using WebUtils; namespace Core { - public interface IPluginTools : IWorkflowTool, ILogTool, IHttpFactoryTool, IFileTool + public interface IPluginTools : IWorkflowTool, ILogTool, IHttpFactory, IFileTool { - ITimeSet TimeSet { get; } + IWebCallTimeSet WebCallTimeSet { get; } + IK8sTimeSet K8STimeSet { get; } /// /// Deletes kubernetes and tracked file resources. @@ -25,13 +27,6 @@ namespace Core ILog GetLog(); } - public interface IHttpFactoryTool - { - IHttp CreateHttp(string id, Action onClientCreated); - IHttp CreateHttp(string id, Action onClientCreated, ITimeSet timeSet); - IHttp CreateHttp(string id); - } - public interface IFileTool { IFileManager GetFileManager(); @@ -40,18 +35,22 @@ namespace Core internal class PluginTools : IPluginTools { private readonly WorkflowCreator workflowCreator; + private readonly HttpFactory httpFactory; private readonly IFileManager fileManager; private readonly LogPrefixer log; - internal PluginTools(ILog log, WorkflowCreator workflowCreator, string fileManagerRootFolder, ITimeSet timeSet) + internal PluginTools(ILog log, WorkflowCreator workflowCreator, string fileManagerRootFolder, IWebCallTimeSet webCallTimeSet, IK8sTimeSet k8STimeSet) { this.log = new LogPrefixer(log); this.workflowCreator = workflowCreator; - TimeSet = timeSet; + httpFactory = new HttpFactory(log, webCallTimeSet); + WebCallTimeSet = webCallTimeSet; + K8STimeSet = k8STimeSet; fileManager = new FileManager(log, fileManagerRootFolder); } - public ITimeSet TimeSet { get; } + public IWebCallTimeSet WebCallTimeSet { get; } + public IK8sTimeSet K8STimeSet { get; } public void ApplyLogPrefix(string prefix) { @@ -60,17 +59,17 @@ namespace Core public IHttp CreateHttp(string id, Action onClientCreated) { - return CreateHttp(id, onClientCreated, TimeSet); + return httpFactory.CreateHttp(id, onClientCreated); } - public IHttp CreateHttp(string id, Action onClientCreated, ITimeSet ts) + public IHttp CreateHttp(string id, Action onClientCreated, IWebCallTimeSet timeSet) { - return new Http(id, log, ts, onClientCreated); + return httpFactory.CreateHttp(id, onClientCreated, timeSet); } public IHttp CreateHttp(string id) { - return new Http(id, log, TimeSet); + return httpFactory.CreateHttp(id); } public IStartupWorkflow CreateWorkflow(string? namespaceOverride = null) diff --git a/Framework/Core/ToolsFactory.cs b/Framework/Core/ToolsFactory.cs index 96752b6f..0ca30404 100644 --- a/Framework/Core/ToolsFactory.cs +++ b/Framework/Core/ToolsFactory.cs @@ -1,5 +1,6 @@ using KubernetesWorkflow; using Logging; +using WebUtils; namespace Core { @@ -13,19 +14,21 @@ namespace Core private readonly ILog log; private readonly WorkflowCreator workflowCreator; private readonly string fileManagerRootFolder; - private readonly ITimeSet timeSet; + private readonly IWebCallTimeSet webCallTimeSet; + private readonly IK8sTimeSet k8STimeSet; - public ToolsFactory(ILog log, Configuration configuration, string fileManagerRootFolder, ITimeSet timeSet) + public ToolsFactory(ILog log, Configuration configuration, string fileManagerRootFolder, IWebCallTimeSet webCallTimeSet, IK8sTimeSet k8STimeSet) { this.log = log; workflowCreator = new WorkflowCreator(log, configuration); this.fileManagerRootFolder = fileManagerRootFolder; - this.timeSet = timeSet; + this.webCallTimeSet = webCallTimeSet; + this.k8STimeSet = k8STimeSet; } public PluginTools CreateTools() { - return new PluginTools(log, workflowCreator, fileManagerRootFolder, timeSet); + return new PluginTools(log, workflowCreator, fileManagerRootFolder, webCallTimeSet, k8STimeSet); } } } diff --git a/Framework/KubernetesWorkflow/K8sTimeSet.cs b/Framework/KubernetesWorkflow/K8sTimeSet.cs new file mode 100644 index 00000000..5cfc8468 --- /dev/null +++ b/Framework/KubernetesWorkflow/K8sTimeSet.cs @@ -0,0 +1,42 @@ +namespace Core +{ + public interface IK8sTimeSet + { + /// + /// After a failed K8s operation, wait this long before trying again. + /// + TimeSpan K8sOperationRetryDelay(); + + /// + /// Maximum total time to attempt to perform a successful k8s operation. + /// If k8s operations fail during this timespan, retries will be made. + /// + TimeSpan K8sOperationTimeout(); + } + + public class DefaultK8sTimeSet : IK8sTimeSet + { + public TimeSpan K8sOperationRetryDelay() + { + return TimeSpan.FromSeconds(10); + } + + public TimeSpan K8sOperationTimeout() + { + return TimeSpan.FromMinutes(30); + } + } + + public class LongK8sTimeSet : IK8sTimeSet + { + public TimeSpan K8sOperationRetryDelay() + { + return TimeSpan.FromSeconds(30); + } + + public TimeSpan K8sOperationTimeout() + { + return TimeSpan.FromHours(1); + } + } +} diff --git a/Framework/Utils/EthAccount.cs b/Framework/Utils/EthAccount.cs new file mode 100644 index 00000000..0898a30a --- /dev/null +++ b/Framework/Utils/EthAccount.cs @@ -0,0 +1,20 @@ +namespace Utils +{ + [Serializable] + public class EthAccount + { + public EthAccount(EthAddress ethAddress, string privateKey) + { + EthAddress = ethAddress; + PrivateKey = privateKey; + } + + public EthAddress EthAddress { get; } + public string PrivateKey { get; } + + public override string ToString() + { + return EthAddress.ToString(); + } + } +} diff --git a/ProjectPlugins/GethPlugin/EthAddress.cs b/Framework/Utils/EthAddress.cs similarity index 96% rename from ProjectPlugins/GethPlugin/EthAddress.cs rename to Framework/Utils/EthAddress.cs index 9b32cd27..61c2776c 100644 --- a/ProjectPlugins/GethPlugin/EthAddress.cs +++ b/Framework/Utils/EthAddress.cs @@ -1,4 +1,4 @@ -namespace GethPlugin +namespace Utils { public interface IHasEthAddress { diff --git a/ProjectPlugins/GethPlugin/EthTokenExtensions.cs b/Framework/Utils/EthTokenExtensions.cs similarity index 98% rename from ProjectPlugins/GethPlugin/EthTokenExtensions.cs rename to Framework/Utils/EthTokenExtensions.cs index d85533a9..70bd3bb2 100644 --- a/ProjectPlugins/GethPlugin/EthTokenExtensions.cs +++ b/Framework/Utils/EthTokenExtensions.cs @@ -1,4 +1,4 @@ -namespace GethPlugin +namespace Utils { public class Ether : IComparable { diff --git a/ProjectPlugins/CodexContractsPlugin/TestTokenExtensions.cs b/Framework/Utils/TestTokenExtensions.cs similarity index 98% rename from ProjectPlugins/CodexContractsPlugin/TestTokenExtensions.cs rename to Framework/Utils/TestTokenExtensions.cs index ddd66759..11b23917 100644 --- a/ProjectPlugins/CodexContractsPlugin/TestTokenExtensions.cs +++ b/Framework/Utils/TestTokenExtensions.cs @@ -1,6 +1,6 @@ using System.Numerics; -namespace CodexContractsPlugin +namespace Utils { public class TestToken : IComparable { diff --git a/Framework/Core/Endpoint.cs b/Framework/WebUtils/Endpoint.cs similarity index 97% rename from Framework/Core/Endpoint.cs rename to Framework/WebUtils/Endpoint.cs index 28b0c612..bf1a95a1 100644 --- a/Framework/Core/Endpoint.cs +++ b/Framework/WebUtils/Endpoint.cs @@ -1,11 +1,10 @@ -using Logging; -using Newtonsoft.Json; -using Serialization = Newtonsoft.Json.Serialization; -using System.Net.Http.Headers; +using System.Net.Http.Headers; using System.Net.Http.Json; +using Logging; +using Newtonsoft.Json; using Utils; -namespace Core +namespace WebUtils { public interface IEndpoint { @@ -119,7 +118,7 @@ namespace Core var errors = new List(); var deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings() { - Error = delegate (object? sender, Serialization.ErrorEventArgs args) + Error = delegate (object? sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) { if (args.CurrentObject == args.ErrorContext.OriginalObject) { diff --git a/Framework/Core/Http.cs b/Framework/WebUtils/Http.cs similarity index 91% rename from Framework/Core/Http.cs rename to Framework/WebUtils/Http.cs index 601d2f48..98a68da4 100644 --- a/Framework/Core/Http.cs +++ b/Framework/WebUtils/Http.cs @@ -1,7 +1,7 @@ using Logging; using Utils; -namespace Core +namespace WebUtils { public interface IHttp { @@ -16,16 +16,16 @@ namespace Core private static object lockLock = new object(); private static readonly Dictionary httpLocks = new Dictionary(); private readonly ILog log; - private readonly ITimeSet timeSet; + private readonly IWebCallTimeSet timeSet; private readonly Action onClientCreated; private readonly string id; - internal Http(string id, ILog log, ITimeSet timeSet) + internal Http(string id, ILog log, IWebCallTimeSet timeSet) : this(id, log, timeSet, DoNothing) { } - internal Http(string id, ILog log, ITimeSet timeSet, Action onClientCreated) + internal Http(string id, ILog log, IWebCallTimeSet timeSet, Action onClientCreated) { this.id = id; this.log = log; diff --git a/Framework/WebUtils/HttpFactory.cs b/Framework/WebUtils/HttpFactory.cs new file mode 100644 index 00000000..4d5d7c4c --- /dev/null +++ b/Framework/WebUtils/HttpFactory.cs @@ -0,0 +1,43 @@ +using Logging; + +namespace WebUtils +{ + public interface IHttpFactory + { + IHttp CreateHttp(string id, Action onClientCreated); + IHttp CreateHttp(string id, Action onClientCreated, IWebCallTimeSet timeSet); + IHttp CreateHttp(string id); + } + + public class HttpFactory : IHttpFactory + { + private readonly ILog log; + private readonly IWebCallTimeSet defaultTimeSet; + + public HttpFactory(ILog log) + : this (log, new DefaultWebCallTimeSet()) + { + } + + public HttpFactory(ILog log, IWebCallTimeSet defaultTimeSet) + { + this.log = log; + this.defaultTimeSet = defaultTimeSet; + } + + public IHttp CreateHttp(string id, Action onClientCreated) + { + return CreateHttp(id, onClientCreated, defaultTimeSet); + } + + public IHttp CreateHttp(string id, Action onClientCreated, IWebCallTimeSet ts) + { + return new Http(id, log, ts, onClientCreated); + } + + public IHttp CreateHttp(string id) + { + return new Http(id, log, defaultTimeSet); + } + } +} diff --git a/Framework/Core/TimeSet.cs b/Framework/WebUtils/WebCallTimeSet.cs similarity index 55% rename from Framework/Core/TimeSet.cs rename to Framework/WebUtils/WebCallTimeSet.cs index ce47c450..347a77b8 100644 --- a/Framework/Core/TimeSet.cs +++ b/Framework/WebUtils/WebCallTimeSet.cs @@ -1,6 +1,6 @@ -namespace Core +namespace WebUtils { - public interface ITimeSet + public interface IWebCallTimeSet { /// /// Timeout for a single HTTP call. @@ -17,20 +17,9 @@ /// After a failed HTTP call, wait this long before trying again. /// TimeSpan HttpCallRetryDelay(); - - /// - /// After a failed K8s operation, wait this long before trying again. - /// - TimeSpan K8sOperationRetryDelay(); - - /// - /// Maximum total time to attempt to perform a successful k8s operation. - /// If k8s operations fail during this timespan, retries will be made. - /// - TimeSpan K8sOperationTimeout(); } - public class DefaultTimeSet : ITimeSet + public class DefaultWebCallTimeSet : IWebCallTimeSet { public TimeSpan HttpCallTimeout() { @@ -46,19 +35,9 @@ { return TimeSpan.FromSeconds(1); } - - public TimeSpan K8sOperationRetryDelay() - { - return TimeSpan.FromSeconds(10); - } - - public TimeSpan K8sOperationTimeout() - { - return TimeSpan.FromMinutes(30); - } } - public class LongTimeSet : ITimeSet + public class LongWebCallTimeSet : IWebCallTimeSet { public TimeSpan HttpCallTimeout() { @@ -74,15 +53,5 @@ { return TimeSpan.FromSeconds(20); } - - public TimeSpan K8sOperationRetryDelay() - { - return TimeSpan.FromSeconds(30); - } - - public TimeSpan K8sOperationTimeout() - { - return TimeSpan.FromHours(1); - } } } diff --git a/Framework/WebUtils/WebUtils.csproj b/Framework/WebUtils/WebUtils.csproj new file mode 100644 index 00000000..743cc777 --- /dev/null +++ b/Framework/WebUtils/WebUtils.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/ProjectPlugins/CodexPlugin/CodexAccess.cs b/ProjectPlugins/CodexClient/CodexAccess.cs similarity index 73% rename from ProjectPlugins/CodexPlugin/CodexAccess.cs rename to ProjectPlugins/CodexClient/CodexAccess.cs index 227956e5..f700331d 100644 --- a/ProjectPlugins/CodexPlugin/CodexAccess.cs +++ b/ProjectPlugins/CodexClient/CodexAccess.cs @@ -1,26 +1,25 @@ using CodexOpenApi; -using Core; -using GethPlugin; using Logging; using Newtonsoft.Json; using Utils; +using WebUtils; -namespace CodexPlugin +namespace CodexClient { public class CodexAccess { private readonly ILog log; - private readonly IPluginTools tools; + private readonly IHttpFactory httpFactory; private readonly IProcessControl processControl; private ICodexInstance instance; private readonly Mapper mapper = new Mapper(); - public CodexAccess(IPluginTools tools, IProcessControl processControl, ICodexInstance instance, ICrashWatcher crashWatcher) + public CodexAccess(ILog log, IHttpFactory httpFactory, IProcessControl processControl, ICodexInstance instance, ICrashWatcher crashWatcher) { - this.tools = tools; + this.log = log; + this.httpFactory = httpFactory; this.processControl = processControl; this.instance = instance; - log = tools.GetLog(); CrashWatcher = crashWatcher; CrashWatcher.Start(); @@ -103,19 +102,14 @@ namespace CodexPlugin }); } - public string UploadFile(UploadInput uploadInput, Action onFailure) + public string UploadFile(UploadInput uploadInput) { - return OnCodex( - api => api.UploadAsync(uploadInput.ContentType, uploadInput.ContentDisposition, uploadInput.FileStream), - CreateRetryConfig(nameof(UploadFile), onFailure)); + return OnCodex(api => api.UploadAsync(uploadInput.ContentType, uploadInput.ContentDisposition, uploadInput.FileStream)); } - public Stream DownloadFile(string contentId, Action onFailure) + public Stream DownloadFile(string contentId) { - var fileResponse = OnCodex( - api => api.DownloadNetworkStreamAsync(contentId), - CreateRetryConfig(nameof(DownloadFile), onFailure)); - + var fileResponse = OnCodex(api => api.DownloadNetworkStreamAsync(contentId)); if (fileResponse.StatusCode != 200) throw new Exception("Download failed with StatusCode: " + fileResponse.StatusCode); return fileResponse.Stream; } @@ -147,7 +141,6 @@ namespace CodexPlugin return JsonConvert.DeserializeObject(str)!; }, nameof(LocalFiles)); })); - } public StorageAvailability SalesAvailability(StorageAvailability request) @@ -227,22 +220,22 @@ namespace CodexPlugin processControl.DeleteDataDirFolder(instance); } - private T OnCodex(Func> action) + private T OnCodex(Func> action) { - var result = tools.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action)); + var result = httpFactory.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action)); return result; } - private T OnCodex(Func> action, Retry retry) + private T OnCodex(Func> action, Retry retry) { - var result = tools.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action), retry); + var result = httpFactory.CreateHttp(GetHttpId(), CheckContainerCrashed).OnClient(client => CallCodex(client, action), retry); return result; } - private T CallCodex(HttpClient client, Func> action) + private T CallCodex(HttpClient client, Func> action) { var address = GetAddress(); - var api = new CodexApi(client); + var api = new openapiClient(client); api.BaseUrl = $"{address.Host}:{address.Port}/api/codex/v1"; return CrashCheck(() => Time.Wait(action(api))); } @@ -261,7 +254,7 @@ namespace CodexPlugin private IEndpoint GetEndpoint() { - return tools + return httpFactory .CreateHttp(GetHttpId(), CheckContainerCrashed) .CreateEndpoint(GetAddress(), "/api/codex/v1/", GetName()); } @@ -281,49 +274,6 @@ namespace CodexPlugin if (CrashWatcher.HasCrashed()) throw new Exception($"Container {GetName()} has crashed."); } - private Retry CreateRetryConfig(string description, Action onFailure) - { - var timeSet = tools.TimeSet; - - return new Retry(description, timeSet.HttpRetryTimeout(), timeSet.HttpCallRetryDelay(), failure => - { - onFailure(failure); - Investigate(failure, timeSet); - }); - } - - private void Investigate(Failure failure, ITimeSet timeSet) - { - Log($"Retry {failure.TryNumber} took {Time.FormatDuration(failure.Duration)} and failed with '{failure.Exception}'. " + - $"(HTTP timeout = {Time.FormatDuration(timeSet.HttpCallTimeout())}) " + - $"Checking if node responds to debug/info..."); - - try - { - var debugInfo = GetDebugInfo(); - if (string.IsNullOrEmpty(debugInfo.Spr)) - { - Log("Did not get value debug/info response."); - Throw(failure); - } - else - { - Log("Got valid response from debug/info."); - } - } - catch (Exception ex) - { - Log("Got exception from debug/info call: " + ex); - Throw(failure); - } - - if (failure.Duration < timeSet.HttpCallTimeout()) - { - Log("Retry failed within HTTP timeout duration."); - Throw(failure); - } - } - private void Throw(Failure failure) { throw failure.Exception; diff --git a/ProjectPlugins/CodexClient/CodexClient.csproj b/ProjectPlugins/CodexClient/CodexClient.csproj new file mode 100644 index 00000000..dc11b863 --- /dev/null +++ b/ProjectPlugins/CodexClient/CodexClient.csproj @@ -0,0 +1,39 @@ + + + + net8.0 + enable + enable + + + + + + + + + NSwagCSharp + CodexOpenApi + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + diff --git a/ProjectPlugins/CodexClient/CodexInstance.cs b/ProjectPlugins/CodexClient/CodexInstance.cs new file mode 100644 index 00000000..54c2e9c3 --- /dev/null +++ b/ProjectPlugins/CodexClient/CodexInstance.cs @@ -0,0 +1,40 @@ +using Utils; + +namespace CodexClient +{ + public interface ICodexInstance + { + string Name { get; } + string ImageName { get; } + DateTime StartUtc { get; } + Address DiscoveryEndpoint { get; } + Address ApiEndpoint { get; } + Address ListenEndpoint { get; } + EthAccount? EthAccount { get; } + Address? MetricsEndpoint { get; } + } + + public class CodexInstance : ICodexInstance + { + public CodexInstance(string name, string imageName, DateTime startUtc, Address discoveryEndpoint, Address apiEndpoint, Address listenEndpoint, EthAccount? ethAccount, Address? metricsEndpoint) + { + Name = name; + ImageName = imageName; + StartUtc = startUtc; + DiscoveryEndpoint = discoveryEndpoint; + ApiEndpoint = apiEndpoint; + ListenEndpoint = listenEndpoint; + EthAccount = ethAccount; + MetricsEndpoint = metricsEndpoint; + } + + public string Name { get; } + public string ImageName { get; } + public DateTime StartUtc { get; } + public Address DiscoveryEndpoint { get; } + public Address ApiEndpoint { get; } + public Address ListenEndpoint { get; } + public EthAccount? EthAccount { get; } + public Address? MetricsEndpoint { get; } + } +} diff --git a/ProjectPlugins/CodexPlugin/CodexLogLevel.cs b/ProjectPlugins/CodexClient/CodexLogLevel.cs similarity index 82% rename from ProjectPlugins/CodexPlugin/CodexLogLevel.cs rename to ProjectPlugins/CodexClient/CodexLogLevel.cs index a859a0c4..70cd2e3c 100644 --- a/ProjectPlugins/CodexPlugin/CodexLogLevel.cs +++ b/ProjectPlugins/CodexClient/CodexLogLevel.cs @@ -1,4 +1,4 @@ -namespace CodexPlugin +namespace CodexClient { public enum CodexLogLevel { diff --git a/ProjectPlugins/CodexPlugin/CodexLogLine.cs b/ProjectPlugins/CodexClient/CodexLogLine.cs similarity index 99% rename from ProjectPlugins/CodexPlugin/CodexLogLine.cs rename to ProjectPlugins/CodexClient/CodexLogLine.cs index d2758145..01f90775 100644 --- a/ProjectPlugins/CodexPlugin/CodexLogLine.cs +++ b/ProjectPlugins/CodexClient/CodexLogLine.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace CodexPlugin +namespace CodexClient { public class CodexLogLine { diff --git a/ProjectPlugins/CodexPlugin/CodexNode.cs b/ProjectPlugins/CodexClient/CodexNode.cs similarity index 87% rename from ProjectPlugins/CodexPlugin/CodexNode.cs rename to ProjectPlugins/CodexClient/CodexNode.cs index 12cf0f28..90f09557 100644 --- a/ProjectPlugins/CodexPlugin/CodexNode.cs +++ b/ProjectPlugins/CodexClient/CodexNode.cs @@ -1,14 +1,11 @@ -using CodexPlugin.Hooks; -using Core; +using CodexClient.Hooks; using FileUtils; -using GethPlugin; using Logging; -using MetricsPlugin; using Utils; -namespace CodexPlugin +namespace CodexClient { - public interface ICodexNode : IHasMetricsScrapeTarget, IHasEthAddress + public partial interface ICodexNode : IHasEthAddress { string GetName(); string GetImageName(); @@ -17,10 +14,8 @@ namespace CodexPlugin string GetSpr(); DebugPeer GetDebugPeer(string peerId); ContentId UploadFile(TrackedFile file); - ContentId UploadFile(TrackedFile file, Action onFailure); - ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition, Action onFailure); + ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition); TrackedFile? DownloadContent(ContentId contentId, string fileLabel = ""); - TrackedFile? DownloadContent(ContentId contentId, Action onFailure, string fileLabel = ""); LocalDataset DownloadStreamless(ContentId cid); /// /// TODO: This will monitor the quota-used of the node until 'size' bytes are added. That's a very bad way @@ -54,23 +49,23 @@ namespace CodexPlugin { private const string UploadFailedMessage = "Unable to store block"; private readonly ILog log; - private readonly IPluginTools tools; private readonly ICodexNodeHooks hooks; private readonly TransferSpeeds transferSpeeds; private string peerId = string.Empty; private string nodeId = string.Empty; private readonly CodexAccess codexAccess; + private readonly IFileManager fileManager; - public CodexNode(IPluginTools tools, CodexAccess codexAccess, IMarketplaceAccess marketplaceAccess, ICodexNodeHooks hooks) + public CodexNode(ILog log, CodexAccess codexAccess, IFileManager fileManager, IMarketplaceAccess marketplaceAccess, ICodexNodeHooks hooks) { - this.tools = tools; this.codexAccess = codexAccess; + this.fileManager = fileManager; Marketplace = marketplaceAccess; this.hooks = hooks; Version = new DebugInfoVersion(); transferSpeeds = new TransferSpeeds(); - log = new LogPrefixer(tools.GetLog(), $"{GetName()} "); + this.log = new LogPrefixer(log, $"{GetName()} "); } public void Awake() @@ -156,15 +151,10 @@ namespace CodexPlugin public ContentId UploadFile(TrackedFile file) { - return UploadFile(file, DoNothing); + return UploadFile(file, "application/octet-stream", $"attachment; filename=\"{Path.GetFileName(file.Filename)}\""); } - public ContentId UploadFile(TrackedFile file, Action onFailure) - { - return UploadFile(file, "application/octet-stream", $"attachment; filename=\"{Path.GetFileName(file.Filename)}\"", onFailure); - } - - public ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition, Action onFailure) + public ContentId UploadFile(TrackedFile file, string contentType, string contentDisposition) { using var fileStream = File.OpenRead(file.Filename); var uniqueId = Guid.NewGuid().ToString(); @@ -176,7 +166,7 @@ namespace CodexPlugin var logMessage = $"Uploading file {file.Describe()} with contentType: '{input.ContentType}' and disposition: '{input.ContentDisposition}'..."; var measurement = Stopwatch.Measure(log, logMessage, () => { - return codexAccess.UploadFile(input, onFailure); + return codexAccess.UploadFile(input); }); var response = measurement.Value; @@ -194,17 +184,12 @@ namespace CodexPlugin public TrackedFile? DownloadContent(ContentId contentId, string fileLabel = "") { - return DownloadContent(contentId, DoNothing, fileLabel); - } - - public TrackedFile? DownloadContent(ContentId contentId, Action onFailure, string fileLabel = "") - { - var file = tools.GetFileManager().CreateEmptyFile(fileLabel); + var file = fileManager.CreateEmptyFile(fileLabel); hooks.OnFileDownloading(contentId); Log($"Downloading '{contentId}'..."); var logMessage = $"Downloaded '{contentId}' to '{file.Filename}'"; - var measurement = Stopwatch.Measure(log, logMessage, () => DownloadToFile(contentId.Id, file, onFailure)); + var measurement = Stopwatch.Measure(log, logMessage, () => DownloadToFile(contentId.Id, file)); var size = file.GetFilesize(); transferSpeeds.AddDownloadSample(size, measurement); @@ -337,20 +322,20 @@ namespace CodexPlugin .ToArray(); } - private void DownloadToFile(string contentId, TrackedFile file, Action onFailure) + private void DownloadToFile(string contentId, TrackedFile file) { using var fileStream = File.OpenWrite(file.Filename); - var timeout = tools.TimeSet.HttpCallTimeout(); + var timeout = TimeSpan.FromMinutes(2.0); // todo: make this user-controllable. try { // Type of stream generated by openAPI client does not support timeouts. var start = DateTime.UtcNow; var cts = new CancellationTokenSource(); - var downloadTask = Task.Run((Action)(() => + var downloadTask = Task.Run(() => { - using var downloadStream = this.codexAccess.DownloadFile(contentId, onFailure); - downloadStream.CopyTo((Stream)fileStream); - }), cts.Token); + using var downloadStream = codexAccess.DownloadFile(contentId); + downloadStream.CopyTo(fileStream); + }, cts.Token); while (DateTime.UtcNow - start < timeout) { @@ -411,9 +396,5 @@ namespace CodexPlugin { log.Log(msg); } - - private void DoNothing(Failure failure) - { - } } } diff --git a/ProjectPlugins/CodexPlugin/CodexTypes.cs b/ProjectPlugins/CodexClient/CodexTypes.cs similarity index 99% rename from ProjectPlugins/CodexPlugin/CodexTypes.cs rename to ProjectPlugins/CodexClient/CodexTypes.cs index be5b2295..1d310b34 100644 --- a/ProjectPlugins/CodexPlugin/CodexTypes.cs +++ b/ProjectPlugins/CodexClient/CodexTypes.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using Utils; -namespace CodexPlugin +namespace CodexClient { public class DebugInfo { diff --git a/ProjectPlugins/CodexPlugin/CodexUtils.cs b/ProjectPlugins/CodexClient/CodexUtils.cs similarity index 95% rename from ProjectPlugins/CodexPlugin/CodexUtils.cs rename to ProjectPlugins/CodexClient/CodexUtils.cs index e4cf96e6..b791f049 100644 --- a/ProjectPlugins/CodexPlugin/CodexUtils.cs +++ b/ProjectPlugins/CodexClient/CodexUtils.cs @@ -1,4 +1,4 @@ -namespace CodexPlugin +namespace CodexClient { public static class CodexUtils { diff --git a/ProjectPlugins/CodexPlugin/Hooks/CodexHooksFactory.cs b/ProjectPlugins/CodexClient/Hooks/CodexHooksFactory.cs similarity index 96% rename from ProjectPlugins/CodexPlugin/Hooks/CodexHooksFactory.cs rename to ProjectPlugins/CodexClient/Hooks/CodexHooksFactory.cs index b3a718ea..83e45926 100644 --- a/ProjectPlugins/CodexPlugin/Hooks/CodexHooksFactory.cs +++ b/ProjectPlugins/CodexClient/Hooks/CodexHooksFactory.cs @@ -1,7 +1,6 @@ -using GethPlugin; -using Utils; +using Utils; -namespace CodexPlugin.Hooks +namespace CodexClient.Hooks { public interface ICodexHooksProvider { diff --git a/ProjectPlugins/CodexPlugin/Hooks/CodexNodeHooks.cs b/ProjectPlugins/CodexClient/Hooks/CodexNodeHooks.cs similarity index 91% rename from ProjectPlugins/CodexPlugin/Hooks/CodexNodeHooks.cs rename to ProjectPlugins/CodexClient/Hooks/CodexNodeHooks.cs index b2bf6170..8becef0a 100644 --- a/ProjectPlugins/CodexPlugin/Hooks/CodexNodeHooks.cs +++ b/ProjectPlugins/CodexClient/Hooks/CodexNodeHooks.cs @@ -1,7 +1,6 @@ -using GethPlugin; -using Utils; +using Utils; -namespace CodexPlugin.Hooks +namespace CodexClient.Hooks { public interface ICodexNodeHooks { diff --git a/ProjectPlugins/CodexPlugin/Mapper.cs b/ProjectPlugins/CodexClient/Mapper.cs similarity index 94% rename from ProjectPlugins/CodexPlugin/Mapper.cs rename to ProjectPlugins/CodexClient/Mapper.cs index 73319fe3..5d14fbe6 100644 --- a/ProjectPlugins/CodexPlugin/Mapper.cs +++ b/ProjectPlugins/CodexClient/Mapper.cs @@ -1,10 +1,8 @@ -using CodexContractsPlugin; -using CodexOpenApi; -using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Linq; using System.Numerics; using Utils; -namespace CodexPlugin +namespace CodexClient { public class Mapper { @@ -80,12 +78,12 @@ namespace CodexPlugin }; } - public StorageAvailability[] Map(ICollection availabilities) + public StorageAvailability[] Map(ICollection availabilities) { return availabilities.Select(a => Map(a)).ToArray(); } - public StorageAvailability Map(SalesAvailabilityREAD availability) + public StorageAvailability Map(CodexOpenApi.SalesAvailabilityREAD availability) { return new StorageAvailability ( @@ -142,7 +140,7 @@ namespace CodexPlugin // }; //} - public CodexSpace Map(Space space) + public CodexSpace Map(CodexOpenApi.Space space) { return new CodexSpace { @@ -153,7 +151,7 @@ namespace CodexPlugin }; } - private DebugInfoVersion Map(CodexVersion obj) + private DebugInfoVersion Map(CodexOpenApi.CodexVersion obj) { return new DebugInfoVersion { @@ -162,7 +160,7 @@ namespace CodexPlugin }; } - private DebugInfoTable Map(PeersTable obj) + private DebugInfoTable Map(CodexOpenApi.PeersTable obj) { return new DebugInfoTable { @@ -171,7 +169,7 @@ namespace CodexPlugin }; } - private DebugInfoTableNode Map(Node? token) + private DebugInfoTableNode Map(CodexOpenApi.Node? token) { if (token == null) return new DebugInfoTableNode(); return new DebugInfoTableNode @@ -184,7 +182,7 @@ namespace CodexPlugin }; } - private DebugInfoTableNode[] Map(ICollection nodes) + private DebugInfoTableNode[] Map(ICollection nodes) { if (nodes == null || nodes.Count == 0) { diff --git a/ProjectPlugins/CodexPlugin/MarketplaceAccess.cs b/ProjectPlugins/CodexClient/MarketplaceAccess.cs similarity index 98% rename from ProjectPlugins/CodexPlugin/MarketplaceAccess.cs rename to ProjectPlugins/CodexClient/MarketplaceAccess.cs index 34720df7..c7a14142 100644 --- a/ProjectPlugins/CodexPlugin/MarketplaceAccess.cs +++ b/ProjectPlugins/CodexClient/MarketplaceAccess.cs @@ -1,8 +1,8 @@ -using CodexPlugin.Hooks; +using CodexClient.Hooks; using Logging; using Utils; -namespace CodexPlugin +namespace CodexClient { public interface IMarketplaceAccess { diff --git a/ProjectPlugins/CodexPlugin/MarketplaceTypes.cs b/ProjectPlugins/CodexClient/MarketplaceTypes.cs similarity index 98% rename from ProjectPlugins/CodexPlugin/MarketplaceTypes.cs rename to ProjectPlugins/CodexClient/MarketplaceTypes.cs index 59626298..d0319bee 100644 --- a/ProjectPlugins/CodexPlugin/MarketplaceTypes.cs +++ b/ProjectPlugins/CodexClient/MarketplaceTypes.cs @@ -1,8 +1,7 @@ -using CodexContractsPlugin; -using Logging; +using Logging; using Utils; -namespace CodexPlugin +namespace CodexClient { public class StoragePurchaseRequest { diff --git a/ProjectPlugins/CodexClient/ProcessControl.cs b/ProjectPlugins/CodexClient/ProcessControl.cs new file mode 100644 index 00000000..61dcb8f2 --- /dev/null +++ b/ProjectPlugins/CodexClient/ProcessControl.cs @@ -0,0 +1,11 @@ +using Logging; + +namespace CodexClient +{ + public interface IProcessControl + { + void Stop(ICodexInstance instance, bool waitTillStopped); + IDownloadedLog DownloadLog(ICodexInstance instance, LogFile file); + void DeleteDataDirFolder(ICodexInstance instance); + } +} diff --git a/ProjectPlugins/CodexPlugin/StoragePurchaseContract.cs b/ProjectPlugins/CodexClient/StoragePurchaseContract.cs similarity index 92% rename from ProjectPlugins/CodexPlugin/StoragePurchaseContract.cs rename to ProjectPlugins/CodexClient/StoragePurchaseContract.cs index 487cea43..7e4f0d00 100644 --- a/ProjectPlugins/CodexPlugin/StoragePurchaseContract.cs +++ b/ProjectPlugins/CodexClient/StoragePurchaseContract.cs @@ -1,11 +1,9 @@ -using CodexContractsPlugin; -using CodexPlugin.Hooks; -using GethPlugin; +using CodexClient.Hooks; using Logging; using Newtonsoft.Json; using Utils; -namespace CodexPlugin +namespace CodexClient { public interface IStoragePurchaseContract { @@ -14,7 +12,7 @@ namespace CodexPlugin ContentId ContentId { get; } void WaitForStorageContractSubmitted(); void WaitForStorageContractStarted(); - void WaitForStorageContractFinished(ICodexContracts contracts); + void WaitForStorageContractFinished(); void WaitForContractFailed(); } @@ -65,7 +63,7 @@ namespace CodexPlugin AssertDuration(SubmittedToStarted, timeout, nameof(SubmittedToStarted)); } - public void WaitForStorageContractFinished(ICodexContracts contracts) + public void WaitForStorageContractFinished() { if (!contractStartedUtc.HasValue) { @@ -77,13 +75,6 @@ namespace CodexPlugin contractFinishedUtc = DateTime.UtcNow; LogFinishedDuration(); AssertDuration(SubmittedToFinished, timeout, nameof(SubmittedToFinished)); - - contracts.WaitUntilNextPeriod(); - contracts.WaitUntilNextPeriod(); - - var blocks = 3; - Log($"Waiting {blocks} blocks for nodes to process payouts..."); - Thread.Sleep(GethContainerRecipe.BlockInterval * blocks); } public void WaitForContractFailed() diff --git a/ProjectPlugins/CodexPlugin/TransferSpeeds.cs b/ProjectPlugins/CodexClient/TransferSpeeds.cs similarity index 98% rename from ProjectPlugins/CodexPlugin/TransferSpeeds.cs rename to ProjectPlugins/CodexClient/TransferSpeeds.cs index b745f644..9e013efb 100644 --- a/ProjectPlugins/CodexPlugin/TransferSpeeds.cs +++ b/ProjectPlugins/CodexClient/TransferSpeeds.cs @@ -1,6 +1,6 @@ using Utils; -namespace CodexPlugin +namespace CodexClient { public interface ITransferSpeeds { diff --git a/ProjectPlugins/CodexPlugin/openapi.yaml b/ProjectPlugins/CodexClient/openapi.yaml similarity index 100% rename from ProjectPlugins/CodexPlugin/openapi.yaml rename to ProjectPlugins/CodexClient/openapi.yaml diff --git a/ProjectPlugins/CodexPlugin/CodexInstance.cs b/ProjectPlugins/CodexPlugin/CodexInstanceContainerExtension.cs similarity index 54% rename from ProjectPlugins/CodexPlugin/CodexInstance.cs rename to ProjectPlugins/CodexPlugin/CodexInstanceContainerExtension.cs index 15cde305..5e97dd0f 100644 --- a/ProjectPlugins/CodexPlugin/CodexInstance.cs +++ b/ProjectPlugins/CodexPlugin/CodexInstanceContainerExtension.cs @@ -1,47 +1,10 @@ using Core; -using GethPlugin; using KubernetesWorkflow.Types; using Logging; using Utils; namespace CodexPlugin { - public interface ICodexInstance - { - string Name { get; } - string ImageName { get; } - DateTime StartUtc { get; } - Address DiscoveryEndpoint { get; } - Address ApiEndpoint { get; } - Address ListenEndpoint { get; } - EthAccount? EthAccount { get; } - Address? MetricsEndpoint { get; } - } - - public class CodexInstance : ICodexInstance - { - public CodexInstance(string name, string imageName, DateTime startUtc, Address discoveryEndpoint, Address apiEndpoint, Address listenEndpoint, EthAccount? ethAccount, Address? metricsEndpoint) - { - Name = name; - ImageName = imageName; - StartUtc = startUtc; - DiscoveryEndpoint = discoveryEndpoint; - ApiEndpoint = apiEndpoint; - ListenEndpoint = listenEndpoint; - EthAccount = ethAccount; - MetricsEndpoint = metricsEndpoint; - } - - public string Name { get; } - public string ImageName { get; } - public DateTime StartUtc { get; } - public Address DiscoveryEndpoint { get; } - public Address ApiEndpoint { get; } - public Address ListenEndpoint { get; } - public EthAccount? EthAccount { get; } - public Address? MetricsEndpoint { get; } - } - public static class CodexInstanceContainerExtension { public static ICodexInstance CreateFromPod(RunningPod pod) diff --git a/ProjectPlugins/CodexPlugin/CodexPlugin.csproj b/ProjectPlugins/CodexPlugin/CodexPlugin.csproj index 4e3c96ff..6077bde4 100644 --- a/ProjectPlugins/CodexPlugin/CodexPlugin.csproj +++ b/ProjectPlugins/CodexPlugin/CodexPlugin.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,14 +6,6 @@ enable - - - - - - - - all @@ -30,6 +22,7 @@ + diff --git a/ProjectPlugins/CodexPlugin/CodexStarter.cs b/ProjectPlugins/CodexPlugin/CodexStarter.cs index 9dd44aa6..a2baf96f 100644 --- a/ProjectPlugins/CodexPlugin/CodexStarter.cs +++ b/ProjectPlugins/CodexPlugin/CodexStarter.cs @@ -1,6 +1,5 @@ using CodexPlugin.Hooks; using Core; -using GethPlugin; using KubernetesWorkflow; using KubernetesWorkflow.Types; using Logging; diff --git a/ProjectPlugins/CodexPlugin/OverwatchSupport/CodexNodeTranscriptWriter.cs b/ProjectPlugins/CodexPlugin/OverwatchSupport/CodexNodeTranscriptWriter.cs index 6a6cdfca..c221806e 100644 --- a/ProjectPlugins/CodexPlugin/OverwatchSupport/CodexNodeTranscriptWriter.cs +++ b/ProjectPlugins/CodexPlugin/OverwatchSupport/CodexNodeTranscriptWriter.cs @@ -1,5 +1,4 @@ using CodexPlugin.Hooks; -using GethPlugin; using OverwatchTranscript; using Utils; diff --git a/ProjectPlugins/CodexPlugin/ProcessControl.cs b/ProjectPlugins/CodexPlugin/ProcessControl.cs deleted file mode 100644 index 8b138e49..00000000 --- a/ProjectPlugins/CodexPlugin/ProcessControl.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Logging; - -namespace CodexPlugin -{ - public interface IProcessControl - { - void Stop(ICodexInstance instance, bool waitTillStopped); - IDownloadedLog DownloadLog(ICodexInstance instance, LogFile file); - void DeleteDataDirFolder(ICodexInstance instance); - } - - - //public void DeleteDataDirFolder() - //{ - // try - // { - // var dataDirVar = container.Recipe.EnvVars.Single(e => e.Name == "CODEX_DATA_DIR"); - // var dataDir = dataDirVar.Value; - // var workflow = tools.CreateWorkflow(); - // workflow.ExecuteCommand(container, "rm", "-Rfv", $"/codex/{dataDir}/repo"); - // log.Log("Deleted repo folder."); - // } - // catch (Exception e) - // { - // log.Log("Unable to delete repo folder: " + e); - // } - //} - -} diff --git a/ProjectPlugins/CodexPluginPrebuild/Program.cs b/ProjectPlugins/CodexPluginPrebuild/Program.cs index 3df9f235..fcdf8b5b 100644 --- a/ProjectPlugins/CodexPluginPrebuild/Program.cs +++ b/ProjectPlugins/CodexPluginPrebuild/Program.cs @@ -12,11 +12,12 @@ public static class Program { Console.WriteLine("Injecting hash of 'openapi.yaml'..."); - var root = FindCodexPluginFolder(); - Console.WriteLine("Located CodexPlugin: " + root); - var openApiFile = Path.Combine(root, "openapi.yaml"); - var clientFile = Path.Combine(root, "obj", "openapiClient.cs"); - var targetFile = Path.Combine(root, "ApiChecker.cs"); + var pluginRoot = FindCodexPluginFolder(); + var clientRoot = FindCodexClientFolder(); + Console.WriteLine("Located CodexPlugin: " + pluginRoot); + var openApiFile = Path.Combine(pluginRoot, "openapi.yaml"); + var clientFile = Path.Combine(clientRoot, "obj", "openapiClient.cs"); + var targetFile = Path.Combine(pluginRoot, "ApiChecker.cs"); // Force client rebuild by deleting previous artifact. File.Delete(clientFile); @@ -46,6 +47,13 @@ public static class Program return folder; } + private static string FindCodexClientFolder() + { + var folder = Path.Combine(PluginPathUtils.ProjectPluginsDir, "CodexClient"); + if (!Directory.Exists(folder)) throw new Exception("CodexClient folder not found. Expected: " + folder); + return folder; + } + private static string CreateHash(string openApiFile) { var file = File.ReadAllText(openApiFile); diff --git a/ProjectPlugins/GethPlugin/EthAccount.cs b/ProjectPlugins/GethPlugin/EthAccountGenerator.cs similarity index 55% rename from ProjectPlugins/GethPlugin/EthAccount.cs rename to ProjectPlugins/GethPlugin/EthAccountGenerator.cs index 60bf40d8..ed570947 100644 --- a/ProjectPlugins/GethPlugin/EthAccount.cs +++ b/ProjectPlugins/GethPlugin/EthAccountGenerator.cs @@ -1,20 +1,11 @@ using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.Web3.Accounts; +using Utils; namespace GethPlugin { - [Serializable] - public class EthAccount + public static class EthAccountGenerator { - public EthAccount(EthAddress ethAddress, string privateKey) - { - EthAddress = ethAddress; - PrivateKey = privateKey; - } - - public EthAddress EthAddress { get; } - public string PrivateKey { get; } - public static EthAccount GenerateNew() { var ecKey = Nethereum.Signer.EthECKey.GenerateKey(); @@ -24,10 +15,5 @@ namespace GethPlugin return new EthAccount(ethAddress, account.PrivateKey); } - - public override string ToString() - { - return EthAddress.ToString(); - } } } diff --git a/Tests/CodexReleaseTests/MarketTests/ContractSuccessfulTest.cs b/Tests/CodexReleaseTests/MarketTests/ContractSuccessfulTest.cs index b007945d..d614840f 100644 --- a/Tests/CodexReleaseTests/MarketTests/ContractSuccessfulTest.cs +++ b/Tests/CodexReleaseTests/MarketTests/ContractSuccessfulTest.cs @@ -1,4 +1,5 @@ -using CodexContractsPlugin; +using CodexClient; +using CodexContractsPlugin; using CodexPlugin; using GethPlugin; using NUnit.Framework; diff --git a/Tests/CodexReleaseTests/MarketTests/MultipleContractsTest.cs b/Tests/CodexReleaseTests/MarketTests/MultipleContractsTest.cs index 50293c1d..97876f2b 100644 --- a/Tests/CodexReleaseTests/MarketTests/MultipleContractsTest.cs +++ b/Tests/CodexReleaseTests/MarketTests/MultipleContractsTest.cs @@ -1,4 +1,5 @@ -using CodexContractsPlugin; +using CodexClient; +using CodexContractsPlugin; using CodexPlugin; using GethPlugin; using NUnit.Framework; @@ -37,6 +38,14 @@ namespace CodexReleaseTests.MarketTests All(requests, r => r.WaitForStorageContractFinished(GetContracts())); + // todo: removed from codexclient: + //contracts.WaitUntilNextPeriod(); + //contracts.WaitUntilNextPeriod(); + + //var blocks = 3; + //Log($"Waiting {blocks} blocks for nodes to process payouts..."); + //Thread.Sleep(GethContainerRecipe.BlockInterval * blocks); + // todo: //AssertClientHasPaidForContract(pricePerSlotPerSecond, client, request, hosts); //AssertHostsWerePaidForContract(pricePerSlotPerSecond, request, hosts); diff --git a/Tests/ExperimentalTests/BasicTests/ExampleTests.cs b/Tests/ExperimentalTests/BasicTests/ExampleTests.cs index 50367969..fc83da3b 100644 --- a/Tests/ExperimentalTests/BasicTests/ExampleTests.cs +++ b/Tests/ExperimentalTests/BasicTests/ExampleTests.cs @@ -1,6 +1,5 @@ using CodexPlugin; using DistTestCore; -using GethPlugin; using MetricsPlugin; using NUnit.Framework; using Utils; diff --git a/Tests/ExperimentalTests/BasicTests/MarketplaceTests.cs b/Tests/ExperimentalTests/BasicTests/MarketplaceTests.cs index 16f6dd63..8ce80571 100644 --- a/Tests/ExperimentalTests/BasicTests/MarketplaceTests.cs +++ b/Tests/ExperimentalTests/BasicTests/MarketplaceTests.cs @@ -1,4 +1,5 @@ -using CodexContractsPlugin; +using CodexClient; +using CodexContractsPlugin; using CodexContractsPlugin.Marketplace; using CodexPlugin; using FileUtils; @@ -109,6 +110,14 @@ namespace CodexTests.BasicTests purchaseContract.WaitForStorageContractFinished(contracts); + // todo: removed from codexclient: + //contracts.WaitUntilNextPeriod(); + //contracts.WaitUntilNextPeriod(); + + //var blocks = 3; + //Log($"Waiting {blocks} blocks for nodes to process payouts..."); + //Thread.Sleep(GethContainerRecipe.BlockInterval * blocks); + AssertBalance(contracts, client, Is.LessThan(clientInitialBalance), "Buyer was not charged for storage."); Assert.That(contracts.GetRequestState(request), Is.EqualTo(RequestState.Finished)); } diff --git a/Tests/ExperimentalTests/UtilityTests/DiscordBotTests.cs b/Tests/ExperimentalTests/UtilityTests/DiscordBotTests.cs index d157f66e..5559c5f6 100644 --- a/Tests/ExperimentalTests/UtilityTests/DiscordBotTests.cs +++ b/Tests/ExperimentalTests/UtilityTests/DiscordBotTests.cs @@ -1,4 +1,5 @@ -using CodexContractsPlugin; +using CodexClient; +using CodexContractsPlugin; using CodexDiscordBotPlugin; using CodexPlugin; using Core; @@ -46,6 +47,15 @@ namespace CodexTests.UtilityTests var purchaseContract = ClientPurchasesStorage(client); purchaseContract.WaitForStorageContractStarted(); purchaseContract.WaitForStorageContractFinished(contracts); + + // todo: removed from codexclient: + //contracts.WaitUntilNextPeriod(); + //contracts.WaitUntilNextPeriod(); + + //var blocks = 3; + //Log($"Waiting {blocks} blocks for nodes to process payouts..."); + //Thread.Sleep(GethContainerRecipe.BlockInterval * blocks); + Thread.Sleep(rewarderInterval * 3); apiCalls.Stop(); diff --git a/Tools/KeyMaker/Controllers/KeyController.cs b/Tools/KeyMaker/Controllers/KeyController.cs index dd218893..09644e9c 100644 --- a/Tools/KeyMaker/Controllers/KeyController.cs +++ b/Tools/KeyMaker/Controllers/KeyController.cs @@ -1,5 +1,5 @@ -using GethPlugin; using Microsoft.AspNetCore.Mvc; +using Utils; namespace KeyMaker.Controllers { diff --git a/cs-codex-dist-testing.sln b/cs-codex-dist-testing.sln index 7ba4155b..9b1c0977 100644 --- a/cs-codex-dist-testing.sln +++ b/cs-codex-dist-testing.sln @@ -82,6 +82,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExperimentalTests", "Tests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockchainUtils", "Framework\BlockchainUtils\BlockchainUtils.csproj", "{4648B5AA-A0A7-44BA-89BC-2FD57370943C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodexClient", "ProjectPlugins\CodexClient\CodexClient.csproj", "{9AF12703-29AF-416D-9781-204223D6D0E5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebUtils", "Framework\WebUtils\WebUtils.csproj", "{372C9E5D-5453-4D45-9948-E9324E21AD65}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -220,6 +224,14 @@ Global {4648B5AA-A0A7-44BA-89BC-2FD57370943C}.Debug|Any CPU.Build.0 = Debug|Any CPU {4648B5AA-A0A7-44BA-89BC-2FD57370943C}.Release|Any CPU.ActiveCfg = Release|Any CPU {4648B5AA-A0A7-44BA-89BC-2FD57370943C}.Release|Any CPU.Build.0 = Release|Any CPU + {9AF12703-29AF-416D-9781-204223D6D0E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9AF12703-29AF-416D-9781-204223D6D0E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9AF12703-29AF-416D-9781-204223D6D0E5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9AF12703-29AF-416D-9781-204223D6D0E5}.Release|Any CPU.Build.0 = Release|Any CPU + {372C9E5D-5453-4D45-9948-E9324E21AD65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -258,6 +270,8 @@ Global {639A0603-4E80-465B-BB59-AB02F1DEEF5A} = {88C2A621-8A98-4D07-8625-7900FC8EF89E} {BA7369CD-7C2F-4075-8E35-98BCC19EE203} = {88C2A621-8A98-4D07-8625-7900FC8EF89E} {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} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {237BF0AA-9EC4-4659-AD9A-65DEB974250C}