diff --git a/CodexContractsPlugin/CodexContractsContainerConfig.cs b/CodexContractsPlugin/CodexContractsContainerConfig.cs index 876c9b1a..fc742a4f 100644 --- a/CodexContractsPlugin/CodexContractsContainerConfig.cs +++ b/CodexContractsPlugin/CodexContractsContainerConfig.cs @@ -1,5 +1,4 @@ using GethPlugin; -using KubernetesWorkflow; namespace CodexContractsPlugin { diff --git a/CodexContractsPlugin/CodexContractsContainerRecipe.cs b/CodexContractsPlugin/CodexContractsContainerRecipe.cs index caf3be97..d9ec1f88 100644 --- a/CodexContractsPlugin/CodexContractsContainerRecipe.cs +++ b/CodexContractsPlugin/CodexContractsContainerRecipe.cs @@ -4,11 +4,13 @@ namespace CodexContractsPlugin { public class CodexContractsContainerRecipe : ContainerRecipeFactory { + public static string DockerImage { get; } = "codexstorage/codex-contracts-eth:latest-dist-tests"; + public const string MarketplaceAddressFilename = "/hardhat/deployments/codexdisttestnetwork/Marketplace.json"; public const string MarketplaceArtifactFilename = "/hardhat/artifacts/contracts/Marketplace.sol/Marketplace.json"; public override string AppName => "codex-contracts"; - public override string Image => "codexstorage/codex-contracts-eth:latest-dist-tests"; + public override string Image => DockerImage; protected override void Initialize(StartupConfig startupConfig) { diff --git a/CodexContractsPlugin/CodexContractsPlugin.cs b/CodexContractsPlugin/CodexContractsPlugin.cs index beeb233e..6dadfe74 100644 --- a/CodexContractsPlugin/CodexContractsPlugin.cs +++ b/CodexContractsPlugin/CodexContractsPlugin.cs @@ -18,12 +18,12 @@ namespace CodexContractsPlugin public void Announce() { - //tools.GetLog().Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}'"); + tools.GetLog().Log($"Loaded Codex-Marketplace SmartContracts"); } public void AddMetadata(IAddMetadata metadata) { - //metadata.Add("codexid", codexStarter.GetCodexId()); + metadata.Add("codexcontractsid", CodexContractsContainerRecipe.DockerImage); } public void Decommission() @@ -34,18 +34,5 @@ namespace CodexContractsPlugin { return starter.Start(gethNode); } - - //public RunningContainers[] StartCodexNodes(int numberOfNodes, Action setup) - //{ - // var codexSetup = new CodexSetup(numberOfNodes); - // codexSetup.LogLevel = defaultLogLevel; - // setup(codexSetup); - // return codexStarter.BringOnline(codexSetup); - //} - - //public ICodexNodeGroup WrapCodexContainers(RunningContainers[] containers) - //{ - // return codexStarter.WrapCodexContainers(containers); - //} } } diff --git a/CodexContractsPlugin/CodexContractsStarter.cs b/CodexContractsPlugin/CodexContractsStarter.cs index 01640c12..92085bbc 100644 --- a/CodexContractsPlugin/CodexContractsStarter.cs +++ b/CodexContractsPlugin/CodexContractsStarter.cs @@ -17,7 +17,7 @@ namespace CodexContractsPlugin public ICodexContracts Start(IGethNode gethNode) { - Log("Deploying Codex Marketplace..."); + Log("Deploying Codex SmartContracts..."); var workflow = tools.CreateWorkflow(); var startupConfig = CreateStartupConfig(gethNode); @@ -41,7 +41,11 @@ namespace CodexContractsPlugin var interaction = new ContractInteractions(tools.GetLog(), gethNode); var tokenAddress = interaction.GetTokenAddress(marketplaceAddress); - Log("Extract completed. Marketplace deployed."); + Log("Extract completed. Checking sync..."); + + Time.WaitUntil(() => interaction.IsSynced(marketplaceAddress, abi)); + + Log("Synced. Codex SmartContracts deployed."); return new CodexContractsAccess(tools.GetLog(), marketplaceAddress, abi, tokenAddress); } diff --git a/CodexContractsPlugin/ContractInteractions.cs b/CodexContractsPlugin/ContractInteractions.cs index 9e54b679..b7c64f34 100644 --- a/CodexContractsPlugin/ContractInteractions.cs +++ b/CodexContractsPlugin/ContractInteractions.cs @@ -42,6 +42,18 @@ namespace CodexContractsPlugin return gethNode.Call(tokenAddress, function).ToDecimal(); } + public bool IsSynced(string marketplaceAddress, string marketplaceAbi) + { + try + { + return IsBlockNumberOK() && IsContractAvailable(marketplaceAddress, marketplaceAbi); + } + catch + { + return false; + } + } + private void MintTokens(string account, decimal amount, string tokenAddress) { log.Debug($"({tokenAddress}) {amount} --> {account}"); @@ -55,6 +67,17 @@ namespace CodexContractsPlugin gethNode.SendTransaction(tokenAddress, function); } + + private bool IsBlockNumberOK() + { + var n = gethNode.GetSyncedBlockNumber(); + return n != null && n > 256; + } + + private bool IsContractAvailable(string marketplaceAddress, string marketplaceAbi) + { + return gethNode.IsContractAvailable(marketplaceAbi, marketplaceAddress); + } } [Function("token", "address")] diff --git a/CodexContractsPlugin/MarketplaceAccess.cs b/CodexContractsPlugin/MarketplaceAccess.cs deleted file mode 100644 index bee6cb7d..00000000 --- a/CodexContractsPlugin/MarketplaceAccess.cs +++ /dev/null @@ -1,243 +0,0 @@ -//using DistTestCore.Codex; -//using DistTestCore.Helpers; -//using Logging; -//using Newtonsoft.Json; -//using NUnit.Framework; -//using NUnit.Framework.Constraints; -//using System.Numerics; -//using Utils; - -//namespace DistTestCore.Marketplace -//{ -// public interface IMarketplaceAccess -// { -// string MakeStorageAvailable(ByteSize size, TestToken minPricePerBytePerSecond, TestToken maxCollateral, TimeSpan maxDuration); -// StoragePurchaseContract RequestStorage(ContentId contentId, TestToken pricePerSlotPerSecond, TestToken requiredCollateral, uint minRequiredNumberOfNodes, int proofProbability, TimeSpan duration); -// void AssertThatBalance(IResolveConstraint constraint, string message = ""); -// TestToken GetBalance(); -// } - -// public class MarketplaceAccess : IMarketplaceAccess -// { -// private readonly TestLifecycle lifecycle; -// private readonly MarketplaceNetwork marketplaceNetwork; -// private readonly GethAccount account; -// private readonly CodexAccess codexAccess; - -// public MarketplaceAccess(TestLifecycle lifecycle, MarketplaceNetwork marketplaceNetwork, GethAccount account, CodexAccess codexAccess) -// { -// this.lifecycle = lifecycle; -// this.marketplaceNetwork = marketplaceNetwork; -// this.account = account; -// this.codexAccess = codexAccess; -// } - -// public StoragePurchaseContract RequestStorage(ContentId contentId, TestToken pricePerSlotPerSecond, TestToken requiredCollateral, uint minRequiredNumberOfNodes, int proofProbability, TimeSpan duration) -// { -// var request = new CodexSalesRequestStorageRequest -// { -// duration = ToDecInt(duration.TotalSeconds), -// proofProbability = ToDecInt(proofProbability), -// reward = ToDecInt(pricePerSlotPerSecond), -// collateral = ToDecInt(requiredCollateral), -// expiry = null, -// nodes = minRequiredNumberOfNodes, -// tolerance = null, -// }; - -// Log($"Requesting storage for: {contentId.Id}... (" + -// $"pricePerSlotPerSecond: {pricePerSlotPerSecond}, " + -// $"requiredCollateral: {requiredCollateral}, " + -// $"minRequiredNumberOfNodes: {minRequiredNumberOfNodes}, " + -// $"proofProbability: {proofProbability}, " + -// $"duration: {Time.FormatDuration(duration)})"); - -// var response = codexAccess.RequestStorage(request, contentId.Id); - -// if (response == "Purchasing not available") -// { -// throw new InvalidOperationException(response); -// } - -// Log($"Storage requested successfully. PurchaseId: '{response}'."); - -// return new StoragePurchaseContract(lifecycle.Log, codexAccess, response, duration); -// } - -// public string MakeStorageAvailable(ByteSize totalSpace, TestToken minPriceForTotalSpace, TestToken maxCollateral, TimeSpan maxDuration) -// { -// var request = new CodexSalesAvailabilityRequest -// { -// size = ToDecInt(totalSpace.SizeInBytes), -// duration = ToDecInt(maxDuration.TotalSeconds), -// maxCollateral = ToDecInt(maxCollateral), -// minPrice = ToDecInt(minPriceForTotalSpace) -// }; - -// Log($"Making storage available... (" + -// $"size: {totalSpace}, " + -// $"minPriceForTotalSpace: {minPriceForTotalSpace}, " + -// $"maxCollateral: {maxCollateral}, " + -// $"maxDuration: {Time.FormatDuration(maxDuration)})"); - -// var response = codexAccess.SalesAvailability(request); - -// Log($"Storage successfully made available. Id: {response.id}"); - -// return response.id; -// } - -// private string ToDecInt(double d) -// { -// var i = new BigInteger(d); -// return i.ToString("D"); -// } - -// public string ToDecInt(TestToken t) -// { -// var i = new BigInteger(t.Amount); -// return i.ToString("D"); -// } - -// public void AssertThatBalance(IResolveConstraint constraint, string message = "") -// { -// AssertHelpers.RetryAssert(constraint, GetBalance, message); -// } - -// public TestToken GetBalance() -// { -// var interaction = marketplaceNetwork.StartInteraction(lifecycle); -// var amount = interaction.GetBalance(marketplaceNetwork.Marketplace.TokenAddress, account.Account); -// var balance = new TestToken(amount); - -// Log($"Balance of {account.Account} is {balance}."); - -// return balance; -// } - -// private void Log(string msg) -// { -// lifecycle.Log.Log($"{codexAccess.Container.Name} {msg}"); -// } -// } - -// public class MarketplaceUnavailable : IMarketplaceAccess -// { -// public StoragePurchaseContract RequestStorage(ContentId contentId, TestToken pricePerBytePerSecond, TestToken requiredCollateral, uint minRequiredNumberOfNodes, int proofProbability, TimeSpan duration) -// { -// Unavailable(); -// return null!; -// } - -// public string MakeStorageAvailable(ByteSize size, TestToken minPricePerBytePerSecond, TestToken maxCollateral, TimeSpan duration) -// { -// Unavailable(); -// return string.Empty; -// } - -// public void AssertThatBalance(IResolveConstraint constraint, string message = "") -// { -// Unavailable(); -// } - -// public TestToken GetBalance() -// { -// Unavailable(); -// return new TestToken(0); -// } - -// private void Unavailable() -// { -// Assert.Fail("Incorrect test setup: Marketplace was not enabled for this group of Codex nodes. Add 'EnableMarketplace(...)' after 'SetupCodexNodes()' to enable it."); -// throw new InvalidOperationException(); -// } -// } - -// public class StoragePurchaseContract -// { -// private readonly BaseLog log; -// private readonly CodexAccess codexAccess; -// private DateTime? contractStartUtc; - -// public StoragePurchaseContract(BaseLog log, CodexAccess codexAccess, string purchaseId, TimeSpan contractDuration) -// { -// this.log = log; -// this.codexAccess = codexAccess; -// PurchaseId = purchaseId; -// ContractDuration = contractDuration; -// } - -// public string PurchaseId { get; } -// public TimeSpan ContractDuration { get; } - -// public void WaitForStorageContractStarted() -// { -// WaitForStorageContractStarted(TimeSpan.FromSeconds(30)); -// } - -// public void WaitForStorageContractFinished() -// { -// if (!contractStartUtc.HasValue) -// { -// WaitForStorageContractStarted(); -// } -// var gracePeriod = TimeSpan.FromSeconds(10); -// var currentContractTime = DateTime.UtcNow - contractStartUtc!.Value; -// var timeout = (ContractDuration - currentContractTime) + gracePeriod; -// WaitForStorageContractState(timeout, "finished"); -// } - -// /// -// /// Wait for contract to start. Max timeout depends on contract filesize. Allows more time for larger files. -// /// -// public void WaitForStorageContractStarted(ByteSize contractFileSize) -// { -// var filesizeInMb = contractFileSize.SizeInBytes / (1024 * 1024); -// var maxWaitTime = TimeSpan.FromSeconds(filesizeInMb * 10.0); - -// WaitForStorageContractStarted(maxWaitTime); -// } - -// public void WaitForStorageContractStarted(TimeSpan timeout) -// { -// WaitForStorageContractState(timeout, "started"); -// contractStartUtc = DateTime.UtcNow; -// } - -// private void WaitForStorageContractState(TimeSpan timeout, string desiredState) -// { -// var lastState = ""; -// var waitStart = DateTime.UtcNow; - -// log.Log($"Waiting for {Time.FormatDuration(timeout)} for contract '{PurchaseId}' to reach state '{desiredState}'."); -// while (lastState != desiredState) -// { -// var purchaseStatus = codexAccess.GetPurchaseStatus(PurchaseId); -// var statusJson = JsonConvert.SerializeObject(purchaseStatus); -// if (purchaseStatus != null && purchaseStatus.state != lastState) -// { -// lastState = purchaseStatus.state; -// log.Debug("Purchase status: " + statusJson); -// } - -// Thread.Sleep(1000); - -// if (lastState == "errored") -// { -// Assert.Fail("Contract errored: " + statusJson); -// } - -// if (DateTime.UtcNow - waitStart > timeout) -// { -// Assert.Fail($"Contract did not reach '{desiredState}' within timeout. {statusJson}"); -// } -// } -// log.Log($"Contract '{desiredState}'."); -// } - -// public CodexStoragePurchase GetPurchaseStatus(string purchaseId) -// { -// return codexAccess.GetPurchaseStatus(purchaseId); -// } -// } -//} diff --git a/CodexContractsPlugin/MarketplaceAccessFactory.cs b/CodexContractsPlugin/MarketplaceAccessFactory.cs deleted file mode 100644 index efc68413..00000000 --- a/CodexContractsPlugin/MarketplaceAccessFactory.cs +++ /dev/null @@ -1,41 +0,0 @@ -//using DistTestCore.Codex; - -//namespace DistTestCore.Marketplace -//{ -// public interface IMarketplaceAccessFactory -// { -// IMarketplaceAccess CreateMarketplaceAccess(CodexAccess access); -// } - -// public class MarketplaceUnavailableAccessFactory : IMarketplaceAccessFactory -// { -// public IMarketplaceAccess CreateMarketplaceAccess(CodexAccess access) -// { -// return new MarketplaceUnavailable(); -// } -// } - -// public class GethMarketplaceAccessFactory : IMarketplaceAccessFactory -// { -// private readonly TestLifecycle lifecycle; -// private readonly MarketplaceNetwork marketplaceNetwork; - -// public GethMarketplaceAccessFactory(TestLifecycle lifecycle, MarketplaceNetwork marketplaceNetwork) -// { -// this.lifecycle = lifecycle; -// this.marketplaceNetwork = marketplaceNetwork; -// } - -// public IMarketplaceAccess CreateMarketplaceAccess(CodexAccess access) -// { -// var companionNode = GetGethCompanionNode(access); -// return new MarketplaceAccess(lifecycle, marketplaceNetwork, companionNode, access); -// } - -// private GethAccount GetGethCompanionNode(CodexAccess access) -// { -// var account = access.Container.Recipe.Additionals.Single(a => a is GethAccount); -// return (GethAccount)account; -// } -// } -//} diff --git a/CodexContractsPlugin/MarketplaceNetwork.cs b/CodexContractsPlugin/MarketplaceNetwork.cs deleted file mode 100644 index d828f37c..00000000 --- a/CodexContractsPlugin/MarketplaceNetwork.cs +++ /dev/null @@ -1,21 +0,0 @@ -//using NethereumWorkflow; - -//namespace DistTestCore.Marketplace -//{ -// public class MarketplaceNetwork -// { -// public MarketplaceNetwork(GethBootstrapNodeInfo bootstrap, MarketplaceInfo marketplace) -// { -// Bootstrap = bootstrap; -// Marketplace = marketplace; -// } - -// public GethBootstrapNodeInfo Bootstrap { get; } -// public MarketplaceInfo Marketplace { get; } - -// public NethereumInteraction StartInteraction(TestLifecycle lifecycle) -// { -// return Bootstrap.StartInteraction(lifecycle); -// } -// } -//} diff --git a/CodexPlugin/CodexNodeFactory.cs b/CodexPlugin/CodexNodeFactory.cs index cce9a61e..babae9ec 100644 --- a/CodexPlugin/CodexNodeFactory.cs +++ b/CodexPlugin/CodexNodeFactory.cs @@ -17,23 +17,9 @@ namespace CodexPlugin this.tools = tools; } - //private readonly TestLifecycle lifecycle; - //private readonly IMetricsAccessFactory metricsAccessFactory; - //private readonly IMarketplaceAccessFactory marketplaceAccessFactory; - - //public CodexNodeFactory(TestLifecycle lifecycle, IMetricsAccessFactory metricsAccessFactory, IMarketplaceAccessFactory marketplaceAccessFactory) - //{ - // this.lifecycle = lifecycle; - // this.metricsAccessFactory = metricsAccessFactory; - // this.marketplaceAccessFactory = marketplaceAccessFactory; - //} - public CodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group) { var ethAddress = GetEthAddress(access); - - //var metricsAccess = metricsAccessFactory.CreateMetricsAccess(access.Container); - //var marketplaceAccess = marketplaceAccessFactory.CreateMarketplaceAccess(access); return new CodexNode(tools, access, group, ethAddress); } @@ -42,7 +28,6 @@ namespace CodexPlugin var mStart = access.Container.Recipe.Additionals.SingleOrDefault(a => a is MarketplaceStartResults) as MarketplaceStartResults; if (mStart == null) return null; return mStart.EthAddress; - } } } diff --git a/CodexPlugin/CodexPlugin.cs b/CodexPlugin/CodexPlugin.cs index 599ca242..fe634600 100644 --- a/CodexPlugin/CodexPlugin.cs +++ b/CodexPlugin/CodexPlugin.cs @@ -39,9 +39,9 @@ namespace CodexPlugin return codexStarter.BringOnline(codexSetup); } - public ICodexNodeGroup WrapCodexContainers(RunningContainers[] containers) + public ICodexNodeGroup WrapCodexContainers(CoreInterface coreInterface, RunningContainers[] containers) { - return codexStarter.WrapCodexContainers(containers); + return codexStarter.WrapCodexContainers(coreInterface, containers); } } } diff --git a/CodexPlugin/CodexSetup.cs b/CodexPlugin/CodexSetup.cs index 18177911..00719a00 100644 --- a/CodexPlugin/CodexSetup.cs +++ b/CodexPlugin/CodexSetup.cs @@ -17,10 +17,6 @@ namespace CodexPlugin ICodexSetup WithBlockMaintenanceNumber(int numberOfBlocks); ICodexSetup EnableMetrics(); ICodexSetup EnableMarketplace(IGethNode gethNode, ICodexContracts codexContracts, bool isValidator = false); - - //ICodexSetup EnableMarketplace(TestToken initialBalance); - //ICodexSetup EnableMarketplace(TestToken initialBalance, Ether initialEther); - //ICodexSetup EnableMarketplace(TestToken initialBalance, Ether initialEther, bool isValidator); } public class CodexSetup : CodexStartupConfig, ICodexSetup @@ -92,22 +88,6 @@ namespace CodexPlugin return this; } - //public ICodexSetup EnableMarketplace(TestToken initialBalance) - //{ - // return EnableMarketplace(initialBalance, 1000.Eth()); - //} - - //public ICodexSetup EnableMarketplace(TestToken initialBalance, Ether initialEther) - //{ - // return EnableMarketplace(initialBalance, initialEther, false); - //} - - //public ICodexSetup EnableMarketplace(TestToken initialBalance, Ether initialEther, bool isValidator) - //{ - // MarketplaceConfig = new MarketplaceInitialConfig(initialEther, initialBalance, isValidator); - // return this; - //} - public string Describe() { var args = string.Join(',', DescribeArgs()); diff --git a/CodexPlugin/CodexStarter.cs b/CodexPlugin/CodexStarter.cs index 69a82e81..3c987da5 100644 --- a/CodexPlugin/CodexStarter.cs +++ b/CodexPlugin/CodexStarter.cs @@ -19,19 +19,11 @@ namespace CodexPlugin { LogSeparator(); Log($"Starting {codexSetup.Describe()}..."); - //var gethStartResult = lifecycle.GethStarter.BringOnlineMarketplaceFor(codexSetup); - var startupConfig = CreateStartupConfig(/*gethStartResult,*/ codexSetup); + var startupConfig = CreateStartupConfig(codexSetup); var containers = StartCodexContainers(startupConfig, codexSetup.NumberOfNodes, codexSetup.Location); - //var metricAccessFactory = CollectMetrics(codexSetup, containers); - - //var codexNodeFactory = new CodexNodeFactory(lifecycle, metricAccessFactory, gethStartResult.MarketplaceAccessFactory); - - //var group = CreateCodexGroup(codexSetup, containers, codexNodeFactory); - //lifecycle.SetCodexVersion(group.Version); - var podInfos = string.Join(", ", containers.Containers().Select(c => $"Container: '{c.Name}' runs at '{c.Pod.PodInfo.K8SNodeName}'={c.Pod.PodInfo.Ip}")); Log($"Started {codexSetup.NumberOfNodes} nodes of image '{containers.Containers().First().Recipe.Image}'. ({podInfos})"); LogSeparator(); @@ -39,13 +31,11 @@ namespace CodexPlugin return containers; } - public ICodexNodeGroup WrapCodexContainers(RunningContainers[] containers) + public ICodexNodeGroup WrapCodexContainers(CoreInterface coreInterface, RunningContainers[] containers) { - //var metricAccessFactory = CollectMetrics(codexSetup, containers); + var codexNodeFactory = new CodexNodeFactory(pluginTools); - var codexNodeFactory = new CodexNodeFactory(pluginTools);// (lifecycle, metricAccessFactory, gethStartResult.MarketplaceAccessFactory); - - var group = CreateCodexGroup(containers, codexNodeFactory); + var group = CreateCodexGroup(coreInterface, containers, codexNodeFactory); Log($"Codex version: {group.Version}"); versionResponse = group.Version; @@ -71,39 +61,12 @@ namespace CodexPlugin return recipe.Image; } - //public void DeleteAllResources() - //{ - // //var workflow = CreateWorkflow(); - // //workflow.DeleteTestResources(); - //} - - //public void DownloadLog(RunningContainer container, ILogHandler logHandler, int? tailLines) - //{ - // //var workflow = CreateWorkflow(); - // //workflow.DownloadContainerLog(container, logHandler, tailLines); - //} - - //private IMetricsAccessFactory CollectMetrics(CodexSetup codexSetup, RunningContainers[] containers) - //{ - // if (codexSetup.MetricsMode == MetricsMode.None) return new MetricsUnavailableAccessFactory(); - - // var runningContainers = lifecycle.PrometheusStarter.CollectMetricsFor(containers); - - // if (codexSetup.MetricsMode == MetricsMode.Dashboard) - // { - // lifecycle.GrafanaStarter.StartDashboard(runningContainers.Containers.First(), codexSetup); - // } - - // return new CodexNodeMetricsAccessFactory(lifecycle, runningContainers); - //} - - private StartupConfig CreateStartupConfig(/*GethStartResult gethStartResult, */ CodexSetup codexSetup) + private StartupConfig CreateStartupConfig(CodexSetup codexSetup) { var startupConfig = new StartupConfig(); startupConfig.NameOverride = codexSetup.NameOverride; startupConfig.CreateCrashWatcher = true; startupConfig.Add(codexSetup); - //startupConfig.Add(gethStartResult); return startupConfig; } @@ -118,7 +81,7 @@ namespace CodexPlugin return result.ToArray(); } - private CodexNodeGroup CreateCodexGroup(RunningContainers[] runningContainers, CodexNodeFactory codexNodeFactory) + private CodexNodeGroup CreateCodexGroup(CoreInterface coreInterface, RunningContainers[] runningContainers, CodexNodeFactory codexNodeFactory) { var group = new CodexNodeGroup(this, pluginTools, runningContainers, codexNodeFactory); @@ -128,25 +91,19 @@ namespace CodexPlugin } catch { - CodexNodesNotOnline(runningContainers); + CodexNodesNotOnline(coreInterface, runningContainers); throw; } return group; } - private void CodexNodesNotOnline(RunningContainers[] runningContainers) + private void CodexNodesNotOnline(CoreInterface coreInterface, RunningContainers[] runningContainers) { Log("Codex nodes failed to start"); - // todo: - //foreach (var container in runningContainers.Containers()) lifecycle.DownloadLog(container); + foreach (var container in runningContainers.Containers()) coreInterface.DownloadLog(container); } - //private StartupWorkflow CreateWorkflow() - //{ - // return lifecycle.WorkflowCreator.CreateWorkflow(); - //} - private void LogSeparator() { Log("----------------------------------------------------------------------------"); diff --git a/CodexPlugin/CoreInterfaceExtensions.cs b/CodexPlugin/CoreInterfaceExtensions.cs index 544c7186..946fa882 100644 --- a/CodexPlugin/CoreInterfaceExtensions.cs +++ b/CodexPlugin/CoreInterfaceExtensions.cs @@ -12,7 +12,7 @@ namespace CodexPlugin public static ICodexNodeGroup WrapCodexContainers(this CoreInterface ci, RunningContainers[] containers) { - return Plugin(ci).WrapCodexContainers(containers); + return Plugin(ci).WrapCodexContainers(ci, containers); } public static ICodexNode SetupCodexNode(this CoreInterface ci) diff --git a/CodexPlugin/MarketplaceInitialConfig.cs b/CodexPlugin/MarketplaceInitialConfig.cs index f1f6af6f..f6a49187 100644 --- a/CodexPlugin/MarketplaceInitialConfig.cs +++ b/CodexPlugin/MarketplaceInitialConfig.cs @@ -15,17 +15,5 @@ namespace CodexPlugin public IGethNode GethNode { get; } public ICodexContracts CodexContracts { get; } public bool IsValidator { get; } - - //public MarketplaceInitialConfig(Ether initialEth, TestToken initialTestTokens, bool isValidator) - //{ - // InitialEth = initialEth; - // InitialTestTokens = initialTestTokens; - // IsValidator = isValidator; - //} - - //public Ether InitialEth { get; } - //public TestToken InitialTestTokens { get; } - //public bool IsValidator { get; } - //public int? AccountIndexOverride { get; set; } } } diff --git a/GethPlugin/GethCompanionNodeInfo.cs b/GethPlugin/GethCompanionNodeInfo.cs deleted file mode 100644 index 8c349c36..00000000 --- a/GethPlugin/GethCompanionNodeInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -//using KubernetesWorkflow; -//using NethereumWorkflow; - -//namespace GethPlugin -//{ -// public class GethCompanionNodeInfo -// { -// public GethCompanionNodeInfo(RunningContainer runningContainer, GethAccount[] accounts) -// { -// RunningContainer = runningContainer; -// Accounts = accounts; -// } - -// public RunningContainer RunningContainer { get; } -// public GethAccount[] Accounts { get; } - -// public NethereumInteraction StartInteraction(TestLifecycle lifecycle, GethAccount account) -// { -// var address = lifecycle.Configuration.GetAddress(RunningContainer); -// var privateKey = account.PrivateKey; - -// var creator = new NethereumInteractionCreator(lifecycle.Log, address.Host, address.Port, privateKey); -// return creator.CreateWorkflow(); -// } -// } -//} diff --git a/GethPlugin/GethContainerInfoExtractor.cs b/GethPlugin/GethContainerInfoExtractor.cs index 649da4f4..51c8728e 100644 --- a/GethPlugin/GethContainerInfoExtractor.cs +++ b/GethPlugin/GethContainerInfoExtractor.cs @@ -36,45 +36,11 @@ namespace GethPlugin return pubKey; } - //public string ExtractMarketplaceAddress() - //{ - // log.Debug(); - // var marketplaceAddress = Retry(FetchMarketplaceAddress); - // if (string.IsNullOrEmpty(marketplaceAddress)) throw new InvalidOperationException("Unable to fetch marketplace account from codex-contracts node. Test infra failure."); - - // return marketplaceAddress; - //} - - //public string ExtractMarketplaceAbi() - //{ - // log.Debug(); - // var marketplaceAbi = Retry(FetchMarketplaceAbi); - // if (string.IsNullOrEmpty(marketplaceAbi)) throw new InvalidOperationException("Unable to fetch marketplace artifacts from codex-contracts node. Test infra failure."); - - // return marketplaceAbi; - //} - private string FetchAccountsCsv() { return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.AccountsFilename); } - //private string FetchMarketplaceAddress() - //{ - // var json = workflow.ExecuteCommand(container, "cat", CodexContractsContainerRecipe.MarketplaceAddressFilename); - // var marketplace = JsonConvert.DeserializeObject(json); - // return marketplace!.address; - //} - - //private string FetchMarketplaceAbi() - //{ - // var json = workflow.ExecuteCommand(container, "cat", CodexContractsContainerRecipe.MarketplaceArtifactFilename); - - // var artifact = JObject.Parse(json); - // var abi = artifact["abi"]; - // return abi!.ToString(Formatting.None); - //} - private string FetchPubKey() { var enodeFinder = new PubKeyFinder(s => log.Debug(s)); @@ -139,9 +105,4 @@ namespace GethPlugin length: closeIndex - openIndex); } } - - //public class MarketplaceJson - //{ - // public string address { get; set; } = string.Empty; - //} } diff --git a/GethPlugin/GethContainerRecipe.cs b/GethPlugin/GethContainerRecipe.cs index 44673a81..5214e0b2 100644 --- a/GethPlugin/GethContainerRecipe.cs +++ b/GethPlugin/GethContainerRecipe.cs @@ -4,6 +4,7 @@ namespace GethPlugin { public class GethContainerRecipe : ContainerRecipeFactory { + public static string DockerImage { get; } = "codexstorage/dist-tests-geth:latest"; private const string defaultArgs = "--ipcdisable --syncmode full"; public const string HttpPortTag = "http_port"; @@ -12,7 +13,7 @@ namespace GethPlugin public const string AccountsFilename = "accounts.csv"; public override string AppName => "geth"; - public override string Image => "codexstorage/dist-tests-geth:latest"; + public override string Image => DockerImage; protected override void Initialize(StartupConfig startupConfig) { diff --git a/GethPlugin/GethNode.cs b/GethPlugin/GethNode.cs index 36139049..170896b2 100644 --- a/GethPlugin/GethNode.cs +++ b/GethPlugin/GethNode.cs @@ -15,6 +15,8 @@ namespace GethPlugin void SendEth(IEthAddress account, Ether eth); TResult Call(string contractAddress, TFunction function) where TFunction : FunctionMessage, new(); void SendTransaction(string contractAddress, TFunction function) where TFunction : FunctionMessage, new(); + decimal? GetSyncedBlockNumber(); + bool IsContractAvailable(string abi, string contractAddress); } public class GethNode : IGethNode @@ -74,5 +76,15 @@ namespace GethPlugin var creator = new NethereumInteractionCreator(log, address.Host, address.Port, account.PrivateKey); return creator.CreateWorkflow(); } + + public decimal? GetSyncedBlockNumber() + { + return StartInteraction().GetSyncedBlockNumber(); + } + + public bool IsContractAvailable(string abi, string contractAddress) + { + return StartInteraction().IsContractAvailable(abi, contractAddress); + } } } diff --git a/GethPlugin/GethPlugin.cs b/GethPlugin/GethPlugin.cs index ec31cde2..9c2f0bbd 100644 --- a/GethPlugin/GethPlugin.cs +++ b/GethPlugin/GethPlugin.cs @@ -5,22 +5,24 @@ namespace GethPlugin public class GethPlugin : IProjectPlugin, IHasLogPrefix, IHasMetadata { private readonly GethStarter starter; + private readonly IPluginTools tools; public GethPlugin(IPluginTools tools) { starter = new GethStarter(tools); + this.tools = tools; } public string LogPrefix => "(Geth) "; public void Announce() { - //tools.GetLog().Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}'"); + tools.GetLog().Log($"Loaded Geth plugin."); } public void AddMetadata(IAddMetadata metadata) { - //metadata.Add("codexid", codexStarter.GetCodexId()); + metadata.Add("gethid", GethContainerRecipe.DockerImage); } public void Decommission() diff --git a/GethPlugin/GethStarter.cs b/GethPlugin/GethStarter.cs index f6b6c225..dc9246e9 100644 --- a/GethPlugin/GethStarter.cs +++ b/GethPlugin/GethStarter.cs @@ -50,74 +50,5 @@ namespace GethPlugin { tools.GetLog().Log(msg); } - - //public GethStartResult BringOnlineMarketplaceFor(CodexSetup codexSetup) - //{ - // if (codexSetup.MarketplaceConfig == null) return CreateMarketplaceUnavailableResult(); - - // var marketplaceNetwork = marketplaceNetworkCache.Get(); - // var companionNode = StartCompanionNode(codexSetup, marketplaceNetwork); - - // LogStart("Setting up initial balance..."); - // TransferInitialBalance(marketplaceNetwork, codexSetup.MarketplaceConfig, companionNode); - // LogEnd($"Initial balance of {codexSetup.MarketplaceConfig.InitialTestTokens} set for {codexSetup.NumberOfNodes} nodes."); - - // return CreateGethStartResult(marketplaceNetwork, companionNode); - //} - - //private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo companionNode) - //{ - // if (marketplaceConfig.InitialTestTokens.Amount == 0) return; - - // var interaction = marketplaceNetwork.StartInteraction(lifecycle); - // var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress; - - // var accounts = companionNode.Accounts.Select(a => a.Account).ToArray(); - // interaction.MintTestTokens(accounts, marketplaceConfig.InitialTestTokens.Amount, tokenAddress); - //} - - //private GethStartResult CreateGethStartResult(MarketplaceNetwork marketplaceNetwork, GethCompanionNodeInfo companionNode) - //{ - // return new GethStartResult(CreateMarketplaceAccessFactory(marketplaceNetwork), marketplaceNetwork, companionNode); - //} - - //private GethStartResult CreateMarketplaceUnavailableResult() - //{ - // return new GethStartResult(new MarketplaceUnavailableAccessFactory(), null!, null!); - //} - - //private IMarketplaceAccessFactory CreateMarketplaceAccessFactory(MarketplaceNetwork marketplaceNetwork) - //{ - // return new GethMarketplaceAccessFactory(lifecycle, marketplaceNetwork); - //} - - //private GethCompanionNodeInfo StartCompanionNode(CodexSetup codexSetup, MarketplaceNetwork marketplaceNetwork) - //{ - // return companionNodeStarter.StartCompanionNodeFor(codexSetup, marketplaceNetwork); - //} } - - //public class MarketplaceNetworkCache - //{ - // private readonly GethBootstrapNodeStarter bootstrapNodeStarter; - // private readonly CodexContractsStarter codexContractsStarter; - // private MarketplaceNetwork? network; - - // public MarketplaceNetworkCache(GethBootstrapNodeStarter bootstrapNodeStarter, CodexContractsStarter codexContractsStarter) - // { - // this.bootstrapNodeStarter = bootstrapNodeStarter; - // this.codexContractsStarter = codexContractsStarter; - // } - - // public MarketplaceNetwork Get() - // { - // if (network == null) - // { - // var bootstrapInfo = bootstrapNodeStarter.StartGethBootstrapNode(); - // var marketplaceInfo = codexContractsStarter.Start(bootstrapInfo); - // network = new MarketplaceNetwork(bootstrapInfo, marketplaceInfo); - // } - // return network; - // } - //} } diff --git a/Nethereum/NethereumInteraction.cs b/Nethereum/NethereumInteraction.cs index a682ab4d..e3aa5bf4 100644 --- a/Nethereum/NethereumInteraction.cs +++ b/Nethereum/NethereumInteraction.cs @@ -47,39 +47,28 @@ namespace NethereumWorkflow if (!receipt.Succeeded()) throw new Exception("Unable to perform contract transaction."); } - //public bool IsSynced(string marketplaceAddress, string marketplaceAbi) - //{ - // try - // { - // return IsBlockNumberOK() && IsContractAvailable(marketplaceAddress, marketplaceAbi); - // } - // catch - // { - // return false; - // } - //} + public decimal? GetSyncedBlockNumber() + { + log.Debug(); + var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync()); + var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync()); + var numberOfBlocks = number.ToDecimal(); + if (sync.IsSyncing) return null; + return numberOfBlocks; + } - //private bool IsBlockNumberOK() - //{ - // log.Debug(); - // var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync()); - // var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync()); - // var numberOfBlocks = number.ToDecimal(); - // return !sync.IsSyncing && numberOfBlocks > 256; - //} - - //private bool IsContractAvailable(string marketplaceAddress, string marketplaceAbi) - //{ - // log.Debug(); - // try - // { - // var contract = web3.Eth.GetContract(marketplaceAbi, marketplaceAddress); - // return contract != null; - // } - // catch - // { - // return false; - // } - //} + public bool IsContractAvailable(string abi, string contractAddress) + { + log.Debug(); + try + { + var contract = web3.Eth.GetContract(abi, contractAddress); + return contract != null; + } + catch + { + return false; + } + } } }