From 58b1c1e03c89ed049799459ddc9ade21aa189aa0 Mon Sep 17 00:00:00 2001 From: benbierens Date: Tue, 19 Sep 2023 11:51:59 +0200 Subject: [PATCH] Can send eth --- .../CodexContractsContainerRecipe.cs | 4 +- CodexContractsPlugin/CodexContractsStarter.cs | 2 +- CodexContractsPlugin/TestTokenExtensions.cs | 45 +++++++++++++ CodexPlugin/CodexContainerRecipe.cs | 5 +- .../{OnlineCodexNode.cs => CodexNode.cs} | 30 ++++++--- CodexPlugin/CodexNodeFactory.cs | 17 ++++- CodexPlugin/CodexNodeGroup.cs | 16 ++--- CodexPlugin/CodexSetup.cs | 4 +- CodexPlugin/CoreInterfaceExtensions.cs | 4 +- CodexPlugin/MarketplaceStartResults.cs | 8 ++- CodexPlugin/MarketplaceStarter.cs | 6 +- GethPlugin/CoreInterfaceExtensions.cs | 3 +- GethPlugin/EthAddress.cs | 22 +++++++ .../EthTokenExtensions.cs | 48 ++------------ GethPlugin/GethNode.cs | 66 ++++++++++++------- GethPlugin/GethPlugin.cs | 21 ++---- GethPlugin/GethStartResult.cs | 49 +++++++++----- GethPlugin/GethStarter.cs | 13 ++-- MetricsPlugin/CoreInterfaceExtensions.cs | 12 +++- MetricsPlugin/MetricsScrapeTarget.cs | 7 +- Nethereum/NethereumInteraction.cs | 18 +++++ Tests/AutoBootstrapDistTest.cs | 6 +- Tests/BasicTests/ContinuousSubstitute.cs | 12 ++-- Tests/BasicTests/ExampleTests.cs | 10 +-- Tests/BasicTests/NetworkIsolationTest.cs | 2 +- Tests/BasicTests/OneClientTests.cs | 4 +- Tests/BasicTests/TwoClientTests.cs | 4 +- Tests/CodexDistTest.cs | 8 +-- Tests/Helpers/FullConnectivityHelper.cs | 10 +-- Tests/Helpers/PeerConnectionTestHelpers.cs | 2 +- Tests/Helpers/PeerDownloadTestHelpers.cs | 6 +- 31 files changed, 289 insertions(+), 175 deletions(-) create mode 100644 CodexContractsPlugin/TestTokenExtensions.cs rename CodexPlugin/{OnlineCodexNode.cs => CodexNode.cs} (86%) create mode 100644 GethPlugin/EthAddress.cs rename DistTestCore/Tokens.cs => GethPlugin/EthTokenExtensions.cs (50%) diff --git a/CodexContractsPlugin/CodexContractsContainerRecipe.cs b/CodexContractsPlugin/CodexContractsContainerRecipe.cs index 341502f..caf3be9 100644 --- a/CodexContractsPlugin/CodexContractsContainerRecipe.cs +++ b/CodexContractsPlugin/CodexContractsContainerRecipe.cs @@ -14,8 +14,8 @@ namespace CodexContractsPlugin { var config = startupConfig.Get(); - var ip = config.GethNode.RunningContainer.Pod.PodInfo.Ip; - var port = config.GethNode.HttpPort.Number; + var ip = config.GethNode.StartResult.RunningContainer.Pod.PodInfo.Ip; + var port = config.GethNode.StartResult.HttpPort.Number; AddEnvVar("DISTTEST_NETWORK_URL", $"http://{ip}:{port}"); AddEnvVar("HARDHAT_NETWORK", "codexdisttestnetwork"); diff --git a/CodexContractsPlugin/CodexContractsStarter.cs b/CodexContractsPlugin/CodexContractsStarter.cs index 8dcce36..531f0c9 100644 --- a/CodexContractsPlugin/CodexContractsStarter.cs +++ b/CodexContractsPlugin/CodexContractsStarter.cs @@ -38,7 +38,7 @@ namespace CodexContractsPlugin var marketplaceAddress = extractor.ExtractMarketplaceAddress(); var abi = extractor.ExtractMarketplaceAbi(); - var interaction = gethNode.StartInteraction(tools.GetLog()); + var interaction = gethNode.StartInteraction(); var tokenAddress = interaction.GetTokenAddress(marketplaceAddress); Log("Extract completed. Marketplace deployed."); diff --git a/CodexContractsPlugin/TestTokenExtensions.cs b/CodexContractsPlugin/TestTokenExtensions.cs new file mode 100644 index 0000000..a19abde --- /dev/null +++ b/CodexContractsPlugin/TestTokenExtensions.cs @@ -0,0 +1,45 @@ +namespace CodexContractsPlugin +{ + public class TestToken : IComparable + { + public TestToken(decimal amount) + { + Amount = amount; + } + + public decimal Amount { get; } + + public int CompareTo(TestToken? other) + { + return Amount.CompareTo(other!.Amount); + } + + public override bool Equals(object? obj) + { + return obj is TestToken token && Amount == token.Amount; + } + + public override int GetHashCode() + { + return HashCode.Combine(Amount); + } + + public override string ToString() + { + return $"{Amount} TestTokens"; + } + } + + public static class TokensIntExtensions + { + public static TestToken TestTokens(this int i) + { + return TestTokens(Convert.ToDecimal(i)); + } + + public static TestToken TestTokens(this decimal i) + { + return new TestToken(i); + } + } +} diff --git a/CodexPlugin/CodexContainerRecipe.cs b/CodexPlugin/CodexContainerRecipe.cs index 6e82eb3..724f2c4 100644 --- a/CodexPlugin/CodexContainerRecipe.cs +++ b/CodexPlugin/CodexContainerRecipe.cs @@ -80,8 +80,9 @@ namespace CodexPlugin if (config.MarketplaceConfig != null) { var mconfig = config.MarketplaceConfig; - var ip = mconfig.GethNode.RunningContainer.Pod.PodInfo.Ip; - var port = mconfig.GethNode.WsPort.Number; + var gethStart = mconfig.GethNode.StartResult; + var ip = gethStart.RunningContainer.Pod.PodInfo.Ip; + var port = gethStart.WsPort.Number; var marketplaceAddress = mconfig.CodexContracts.MarketplaceAddress; AddEnvVar("CODEX_ETH_PROVIDER", $"ws://{ip}:{port}"); diff --git a/CodexPlugin/OnlineCodexNode.cs b/CodexPlugin/CodexNode.cs similarity index 86% rename from CodexPlugin/OnlineCodexNode.cs rename to CodexPlugin/CodexNode.cs index 4ee798a..6b006c0 100644 --- a/CodexPlugin/OnlineCodexNode.cs +++ b/CodexPlugin/CodexNode.cs @@ -1,5 +1,6 @@ using Core; using FileUtils; +using GethPlugin; using KubernetesWorkflow; using Logging; using MetricsPlugin; @@ -8,28 +9,29 @@ using Utils; namespace CodexPlugin { - public interface IOnlineCodexNode : IHasContainer + public interface ICodexNode : IHasContainer, IHasMetricsScrapeTarget, IHasEthAddress { string GetName(); CodexDebugResponse GetDebugInfo(); CodexDebugPeerResponse GetDebugPeer(string peerId); ContentId UploadFile(TrackedFile file); TrackedFile? DownloadContent(ContentId contentId, string fileLabel = ""); - void ConnectToPeer(IOnlineCodexNode node); + void ConnectToPeer(ICodexNode node); CodexDebugVersionResponse Version { get; } - void BringOffline(); - IMetricsScrapeTarget MetricsScrapeTarget { get; } + void Stop(); } - public class OnlineCodexNode : IOnlineCodexNode + public class CodexNode : ICodexNode { private const string SuccessfullyConnectedMessage = "Successfully connected to peer"; private const string UploadFailedMessage = "Unable to store block"; private readonly IPluginTools tools; + private readonly IEthAddress? ethAddress; - public OnlineCodexNode(IPluginTools tools, CodexAccess codexAccess, CodexNodeGroup group) + public CodexNode(IPluginTools tools, CodexAccess codexAccess, CodexNodeGroup group, IEthAddress? ethAddress) { this.tools = tools; + this.ethAddress = ethAddress; CodexAccess = codexAccess; Group = group; Version = new CodexDebugVersionResponse(); @@ -48,6 +50,14 @@ namespace CodexPlugin return new MetricsScrapeTarget(CodexAccess.Container, port); } } + public IEthAddress EthAddress + { + get + { + if (ethAddress == null) throw new Exception("Marketplace is not enabled for this Codex node. Please start it with the option '.EnableMarketplace(...)' to enable it."); + return ethAddress; + } + } public string GetName() { @@ -95,9 +105,9 @@ namespace CodexPlugin return file; } - public void ConnectToPeer(IOnlineCodexNode node) + public void ConnectToPeer(ICodexNode node) { - var peer = (OnlineCodexNode)node; + var peer = (CodexNode)node; Log($"Connecting to peer {peer.GetName()}..."); var peerInfo = node.GetDebugInfo(); @@ -107,7 +117,7 @@ namespace CodexPlugin Log($"Successfully connected to peer {peer.GetName()}."); } - public void BringOffline() + public void Stop() { if (Group.Count() > 1) throw new InvalidOperationException("Codex-nodes that are part of a group cannot be " + "individually shut down. Use 'BringOffline()' on the group object to stop the group. This method is only " + @@ -132,7 +142,7 @@ namespace CodexPlugin Version = debugInfo.codex; } - private string GetPeerMultiAddress(OnlineCodexNode peer, CodexDebugResponse peerInfo) + private string GetPeerMultiAddress(CodexNode peer, CodexDebugResponse peerInfo) { var multiAddress = peerInfo.addrs.First(); // Todo: Is there a case where First address in list is not the way? diff --git a/CodexPlugin/CodexNodeFactory.cs b/CodexPlugin/CodexNodeFactory.cs index 89b69eb..cce9a61 100644 --- a/CodexPlugin/CodexNodeFactory.cs +++ b/CodexPlugin/CodexNodeFactory.cs @@ -1,10 +1,11 @@ using Core; +using GethPlugin; namespace CodexPlugin { public interface ICodexNodeFactory { - OnlineCodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group); + CodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group); } public class CodexNodeFactory : ICodexNodeFactory @@ -27,11 +28,21 @@ namespace CodexPlugin // this.marketplaceAccessFactory = marketplaceAccessFactory; //} - public OnlineCodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group) + public CodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group) { + var ethAddress = GetEthAddress(access); + //var metricsAccess = metricsAccessFactory.CreateMetricsAccess(access.Container); //var marketplaceAccess = marketplaceAccessFactory.CreateMarketplaceAccess(access); - return new OnlineCodexNode(tools, access, group/*, metricsAccess, marketplaceAccess*/); + return new CodexNode(tools, access, group, ethAddress); + } + + private IEthAddress? GetEthAddress(CodexAccess access) + { + 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/CodexNodeGroup.cs b/CodexPlugin/CodexNodeGroup.cs index 62158d7..cff4f8c 100644 --- a/CodexPlugin/CodexNodeGroup.cs +++ b/CodexPlugin/CodexNodeGroup.cs @@ -5,10 +5,10 @@ using System.Collections; namespace CodexPlugin { - public interface ICodexNodeGroup : IEnumerable, IManyMetricScrapeTargets + public interface ICodexNodeGroup : IEnumerable, IHasManyMetricScrapeTargets { void BringOffline(); - IOnlineCodexNode this[int index] { get; } + ICodexNode this[int index] { get; } } public class CodexNodeGroup : ICodexNodeGroup @@ -23,7 +23,7 @@ namespace CodexPlugin Version = new CodexDebugVersionResponse(); } - public IOnlineCodexNode this[int index] + public ICodexNode this[int index] { get { @@ -35,18 +35,18 @@ namespace CodexPlugin { starter.BringOffline(this); // Clear everything. Prevent accidental use. - Nodes = Array.Empty(); + Nodes = Array.Empty(); Containers = null!; } public RunningContainers[] Containers { get; private set; } - public OnlineCodexNode[] Nodes { get; private set; } + public CodexNode[] Nodes { get; private set; } public CodexDebugVersionResponse Version { get; private set; } public IMetricsScrapeTarget[] ScrapeTargets => Nodes.Select(n => n.MetricsScrapeTarget).ToArray(); - public IEnumerator GetEnumerator() + public IEnumerator GetEnumerator() { - return Nodes.Cast().GetEnumerator(); + return Nodes.Cast().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() @@ -74,7 +74,7 @@ namespace CodexPlugin Version = first; } - private OnlineCodexNode CreateOnlineCodexNode(RunningContainer c, IPluginTools tools, ICodexNodeFactory factory) + private CodexNode CreateOnlineCodexNode(RunningContainer c, IPluginTools tools, ICodexNodeFactory factory) { var access = new CodexAccess(tools, c); return factory.CreateOnlineCodexNode(access, this); diff --git a/CodexPlugin/CodexSetup.cs b/CodexPlugin/CodexSetup.cs index 672165d..1817791 100644 --- a/CodexPlugin/CodexSetup.cs +++ b/CodexPlugin/CodexSetup.cs @@ -10,7 +10,7 @@ namespace CodexPlugin ICodexSetup WithLogLevel(CodexLogLevel logLevel); ICodexSetup WithName(string name); ICodexSetup At(Location location); - ICodexSetup WithBootstrapNode(IOnlineCodexNode node); + ICodexSetup WithBootstrapNode(ICodexNode node); ICodexSetup WithStorageQuota(ByteSize storageQuota); ICodexSetup WithBlockTTL(TimeSpan duration); ICodexSetup WithBlockMaintenanceInterval(TimeSpan duration); @@ -50,7 +50,7 @@ namespace CodexPlugin return this; } - public ICodexSetup WithBootstrapNode(IOnlineCodexNode node) + public ICodexSetup WithBootstrapNode(ICodexNode node) { BootstrapSpr = node.GetDebugInfo().spr; return this; diff --git a/CodexPlugin/CoreInterfaceExtensions.cs b/CodexPlugin/CoreInterfaceExtensions.cs index 75b779f..544c718 100644 --- a/CodexPlugin/CoreInterfaceExtensions.cs +++ b/CodexPlugin/CoreInterfaceExtensions.cs @@ -15,12 +15,12 @@ namespace CodexPlugin return Plugin(ci).WrapCodexContainers(containers); } - public static IOnlineCodexNode SetupCodexNode(this CoreInterface ci) + public static ICodexNode SetupCodexNode(this CoreInterface ci) { return ci.SetupCodexNodes(1)[0]; } - public static IOnlineCodexNode SetupCodexNode(this CoreInterface ci, Action setup) + public static ICodexNode SetupCodexNode(this CoreInterface ci, Action setup) { return ci.SetupCodexNodes(1, setup)[0]; } diff --git a/CodexPlugin/MarketplaceStartResults.cs b/CodexPlugin/MarketplaceStartResults.cs index dd73ed6..6273c1e 100644 --- a/CodexPlugin/MarketplaceStartResults.cs +++ b/CodexPlugin/MarketplaceStartResults.cs @@ -1,15 +1,17 @@ -namespace CodexPlugin +using GethPlugin; + +namespace CodexPlugin { [Serializable] public class MarketplaceStartResults { - public MarketplaceStartResults(string ethAddress, string privateKey) + public MarketplaceStartResults(IEthAddress ethAddress, string privateKey) { EthAddress = ethAddress; PrivateKey = privateKey; } - public string EthAddress { get; } + public IEthAddress EthAddress { get; } public string PrivateKey { get; } } } diff --git a/CodexPlugin/MarketplaceStarter.cs b/CodexPlugin/MarketplaceStarter.cs index dc9d525..42a5851 100644 --- a/CodexPlugin/MarketplaceStarter.cs +++ b/CodexPlugin/MarketplaceStarter.cs @@ -1,4 +1,5 @@ -using Nethereum.Hex.HexConvertors.Extensions; +using GethPlugin; +using Nethereum.Hex.HexConvertors.Extensions; using Nethereum.Web3.Accounts; namespace CodexPlugin @@ -10,8 +11,9 @@ namespace CodexPlugin var ecKey = Nethereum.Signer.EthECKey.GenerateKey(); var privateKey = ecKey.GetPrivateKeyAsBytes().ToHex(); var account = new Account(privateKey); + var ethAddress = new EthAddress(account.Address); - return new MarketplaceStartResults(account.Address, account.PrivateKey); + return new MarketplaceStartResults(ethAddress, account.PrivateKey); } } } diff --git a/GethPlugin/CoreInterfaceExtensions.cs b/GethPlugin/CoreInterfaceExtensions.cs index 34d9d2f..b486c5c 100644 --- a/GethPlugin/CoreInterfaceExtensions.cs +++ b/GethPlugin/CoreInterfaceExtensions.cs @@ -6,7 +6,8 @@ namespace GethPlugin { public static IGethNode StartGethNode(this CoreInterface ci, Action setup) { - return Plugin(ci).StartGeth(setup); + var p = Plugin(ci); + return p.WrapGethContainer(p.StartGeth(setup)); } private static GethPlugin Plugin(CoreInterface ci) diff --git a/GethPlugin/EthAddress.cs b/GethPlugin/EthAddress.cs new file mode 100644 index 0000000..893a76d --- /dev/null +++ b/GethPlugin/EthAddress.cs @@ -0,0 +1,22 @@ +namespace GethPlugin +{ + public interface IEthAddress + { + string Address { get; } + } + + public interface IHasEthAddress + { + IEthAddress EthAddress { get; } + } + + public class EthAddress : IEthAddress + { + public EthAddress(string address) + { + Address = address; + } + + public string Address { get; } + } +} diff --git a/DistTestCore/Tokens.cs b/GethPlugin/EthTokenExtensions.cs similarity index 50% rename from DistTestCore/Tokens.cs rename to GethPlugin/EthTokenExtensions.cs index 5593ffc..950a7e1 100644 --- a/DistTestCore/Tokens.cs +++ b/GethPlugin/EthTokenExtensions.cs @@ -1,13 +1,15 @@ -namespace DistTestCore +namespace GethPlugin { public class Ether : IComparable { public Ether(decimal wei) { Wei = wei; + Eth = wei / TokensIntExtensions.WeiPerEth; } public decimal Wei { get; } + public decimal Eth { get; } public int CompareTo(Ether? other) { @@ -30,49 +32,9 @@ } } - public class TestToken : IComparable - { - public TestToken(decimal amount) - { - Amount = amount; - } - - public decimal Amount { get; } - - public int CompareTo(TestToken? other) - { - return Amount.CompareTo(other!.Amount); - } - - public override bool Equals(object? obj) - { - return obj is TestToken token && Amount == token.Amount; - } - - public override int GetHashCode() - { - return HashCode.Combine(Amount); - } - - public override string ToString() - { - return $"{Amount} TestTokens"; - } - } - public static class TokensIntExtensions { - private const decimal weiPerEth = 1000000000000000000; - - public static TestToken TestTokens(this int i) - { - return TestTokens(Convert.ToDecimal(i)); - } - - public static TestToken TestTokens(this decimal i) - { - return new TestToken(i); - } + public const decimal WeiPerEth = 1000000000000000000; public static Ether Eth(this int i) { @@ -86,7 +48,7 @@ public static Ether Eth(this decimal i) { - return new Ether(i * weiPerEth); + return new Ether(i * WeiPerEth); } public static Ether Wei(this decimal i) diff --git a/GethPlugin/GethNode.cs b/GethPlugin/GethNode.cs index bb096b2..99bfbf9 100644 --- a/GethPlugin/GethNode.cs +++ b/GethPlugin/GethNode.cs @@ -1,47 +1,67 @@ -using KubernetesWorkflow; -using Logging; +using Logging; using NethereumWorkflow; namespace GethPlugin { public interface IGethNode { - RunningContainer RunningContainer { get; } - Port DiscoveryPort { get; } - Port HttpPort { get; } - Port WsPort { get; } + IGethStartResult StartResult { get; } - NethereumInteraction StartInteraction(ILog log); + NethereumInteraction StartInteraction(); + Ether GetEthBalance(); + Ether GetEthBalance(IHasEthAddress address); + Ether GetEthBalance(IEthAddress address); + void SendEth(IHasEthAddress account, Ether eth); + void SendEth(IEthAddress account, Ether eth); } public class GethNode : IGethNode { - public GethNode(RunningContainer runningContainer, AllGethAccounts allAccounts, string pubKey, Port discoveryPort, Port httpPort, Port wsPort) + private readonly ILog log; + + public GethNode(ILog log, IGethStartResult startResult) { - RunningContainer = runningContainer; - AllAccounts = allAccounts; - Account = allAccounts.Accounts[0]; - PubKey = pubKey; - DiscoveryPort = discoveryPort; - HttpPort = httpPort; - WsPort = wsPort; + this.log = log; + StartResult = startResult; + Account = startResult.AllAccounts.Accounts.First(); } - public RunningContainer RunningContainer { get; } - public AllGethAccounts AllAccounts { get; } + public IGethStartResult StartResult { get; } public GethAccount Account { get; } - public string PubKey { get; } - public Port DiscoveryPort { get; } - public Port HttpPort { get; } - public Port WsPort { get; } - public NethereumInteraction StartInteraction(ILog log) + public NethereumInteraction StartInteraction() { - var address = RunningContainer.Address; + var address = StartResult.RunningContainer.Address; var account = Account; var creator = new NethereumInteractionCreator(log, address.Host, address.Port, account.PrivateKey); return creator.CreateWorkflow(); } + + public Ether GetEthBalance() + { + return StartInteraction().GetEthBalance().Eth(); + } + + public Ether GetEthBalance(IHasEthAddress owner) + { + return GetEthBalance(owner.EthAddress); + } + + public Ether GetEthBalance(IEthAddress address) + { + return StartInteraction().GetEthBalance(address.Address).Eth(); + } + + public void SendEth(IHasEthAddress owner, Ether eth) + { + SendEth(owner.EthAddress, eth); + } + + public void SendEth(IEthAddress account, Ether eth) + { + var i = StartInteraction(); + i.SendEth(account.Address, eth.Eth); + } } } diff --git a/GethPlugin/GethPlugin.cs b/GethPlugin/GethPlugin.cs index 645e93a..ec31cde 100644 --- a/GethPlugin/GethPlugin.cs +++ b/GethPlugin/GethPlugin.cs @@ -1,16 +1,13 @@ using Core; -using KubernetesWorkflow; namespace GethPlugin { public class GethPlugin : IProjectPlugin, IHasLogPrefix, IHasMetadata { - private readonly IPluginTools tools; private readonly GethStarter starter; public GethPlugin(IPluginTools tools) { - this.tools = tools; starter = new GethStarter(tools); } @@ -30,24 +27,16 @@ namespace GethPlugin { } - public IGethNode StartGeth(Action setup) + public IGethStartResult StartGeth(Action setup) { var startupConfig = new GethStartupConfig(); setup(startupConfig); return starter.StartGeth(startupConfig); } - //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); - //} + public IGethNode WrapGethContainer(IGethStartResult startResult) + { + return starter.WrapGethContainer(startResult); + } } } diff --git a/GethPlugin/GethStartResult.cs b/GethPlugin/GethStartResult.cs index 79a04a3..90bb895 100644 --- a/GethPlugin/GethStartResult.cs +++ b/GethPlugin/GethStartResult.cs @@ -1,19 +1,34 @@ -//using Newtonsoft.Json; +using KubernetesWorkflow; -//namespace GethPlugin -//{ -// public class GethStartResult -// { -// public GethStartResult(IMarketplaceAccessFactory marketplaceAccessFactory, MarketplaceNetwork marketplaceNetwork, GethCompanionNodeInfo companionNode) -// { -// MarketplaceAccessFactory = marketplaceAccessFactory; -// MarketplaceNetwork = marketplaceNetwork; -// CompanionNode = companionNode; -// } +namespace GethPlugin +{ + public interface IGethStartResult + { + RunningContainer RunningContainer { get; } + Port DiscoveryPort { get; } + Port HttpPort { get; } + Port WsPort { get; } + AllGethAccounts AllAccounts { get; } + string PubKey { get; } + } -// [JsonIgnore] -// public IMarketplaceAccessFactory MarketplaceAccessFactory { get; } -// public MarketplaceNetwork MarketplaceNetwork { get; } -// public GethCompanionNodeInfo CompanionNode { get; } -// } -//} + public class GethStartResult : IGethStartResult + { + public GethStartResult(RunningContainer runningContainer, Port discoveryPort, Port httpPort, Port wsPort, AllGethAccounts allAccounts, string pubKey) + { + RunningContainer = runningContainer; + DiscoveryPort = discoveryPort; + HttpPort = httpPort; + WsPort = wsPort; + AllAccounts = allAccounts; + PubKey = pubKey; + } + + public RunningContainer RunningContainer { get; } + public Port DiscoveryPort { get; } + public Port HttpPort { get; } + public Port WsPort { get; } + public AllGethAccounts AllAccounts { get; } + public string PubKey { get; } + } +} diff --git a/GethPlugin/GethStarter.cs b/GethPlugin/GethStarter.cs index 8cc1b8e..f6b6c22 100644 --- a/GethPlugin/GethStarter.cs +++ b/GethPlugin/GethStarter.cs @@ -12,7 +12,7 @@ namespace GethPlugin this.tools = tools; } - public IGethNode StartGeth(GethStartupConfig gethStartupConfig) + public IGethStartResult StartGeth(GethStartupConfig gethStartupConfig) { Log("Starting Geth bootstrap node..."); @@ -28,7 +28,7 @@ namespace GethPlugin var extractor = new GethContainerInfoExtractor(tools.GetLog(), workflow, container); var accounts = extractor.ExtractAccounts(); var pubKey = extractor.ExtractPubKey(); - + var discoveryPort = container.Recipe.GetPortByTag(GethContainerRecipe.DiscoveryPortTag); if (discoveryPort == null) throw new Exception("Expected discovery port to be created."); var httpPort = container.Recipe.GetPortByTag(GethContainerRecipe.HttpPortTag); @@ -36,11 +36,14 @@ namespace GethPlugin var wsPort = container.Recipe.GetPortByTag(GethContainerRecipe.wsPortTag); if (wsPort == null) throw new Exception("Expected ws port to be created."); - var result = new GethNode(container, accounts, pubKey, discoveryPort, httpPort, wsPort); + Log($"Geth node started."); - Log($"Geth bootstrap node started with account '{result.Account.Account}'"); + return new GethStartResult(container, discoveryPort, httpPort, wsPort, accounts, pubKey); + } - return result; + public IGethNode WrapGethContainer(IGethStartResult startResult) + { + return new GethNode(tools.GetLog(), startResult); } private void Log(string msg) diff --git a/MetricsPlugin/CoreInterfaceExtensions.cs b/MetricsPlugin/CoreInterfaceExtensions.cs index 46a7021..98d36f0 100644 --- a/MetricsPlugin/CoreInterfaceExtensions.cs +++ b/MetricsPlugin/CoreInterfaceExtensions.cs @@ -6,6 +6,11 @@ namespace MetricsPlugin { public static class CoreInterfaceExtensions { + public static RunningContainer StartMetricsCollector(this CoreInterface ci, params IHasMetricsScrapeTarget[] scrapeTargets) + { + return Plugin(ci).StartMetricsCollector(scrapeTargets.Select(t => t.MetricsScrapeTarget).ToArray()); + } + public static RunningContainer StartMetricsCollector(this CoreInterface ci, params IMetricsScrapeTarget[] scrapeTargets) { return Plugin(ci).StartMetricsCollector(scrapeTargets); @@ -16,11 +21,16 @@ namespace MetricsPlugin return Plugin(ci).CreateAccessForTarget(metricsContainer, scrapeTarget); } - public static IMetricsAccess[] GetMetricsFor(this CoreInterface ci, params IManyMetricScrapeTargets[] manyScrapeTargets) + public static IMetricsAccess[] GetMetricsFor(this CoreInterface ci, params IHasManyMetricScrapeTargets[] manyScrapeTargets) { return ci.GetMetricsFor(manyScrapeTargets.SelectMany(t => t.ScrapeTargets).ToArray()); } + public static IMetricsAccess[] GetMetricsFor(this CoreInterface ci, params IHasMetricsScrapeTarget[] scrapeTargets) + { + return ci.GetMetricsFor(scrapeTargets.Select(t => t.MetricsScrapeTarget).ToArray()); + } + public static IMetricsAccess[] GetMetricsFor(this CoreInterface ci, params IMetricsScrapeTarget[] scrapeTargets) { var rc = ci.StartMetricsCollector(scrapeTargets); diff --git a/MetricsPlugin/MetricsScrapeTarget.cs b/MetricsPlugin/MetricsScrapeTarget.cs index e2e1979..2c7bda6 100644 --- a/MetricsPlugin/MetricsScrapeTarget.cs +++ b/MetricsPlugin/MetricsScrapeTarget.cs @@ -9,7 +9,12 @@ namespace MetricsPlugin int Port { get; } } - public interface IManyMetricScrapeTargets + public interface IHasMetricsScrapeTarget + { + IMetricsScrapeTarget MetricsScrapeTarget { get; } + } + + public interface IHasManyMetricScrapeTargets { IMetricsScrapeTarget[] ScrapeTargets { get; } } diff --git a/Nethereum/NethereumInteraction.cs b/Nethereum/NethereumInteraction.cs index dad4633..2e595a6 100644 --- a/Nethereum/NethereumInteraction.cs +++ b/Nethereum/NethereumInteraction.cs @@ -2,6 +2,7 @@ using Nethereum.ABI.FunctionEncoding.Attributes; using Nethereum.Contracts; using Nethereum.Hex.HexTypes; +using Nethereum.RPC.Eth.DTOs; using Nethereum.Web3; using System.Numerics; using Utils; @@ -19,6 +20,23 @@ namespace NethereumWorkflow this.web3 = web3; } + public void SendEth(string toAddress, decimal ethAmount) + { + var receipt = Time.Wait(web3.Eth.GetEtherTransferService().TransferEtherAndWaitForReceiptAsync(toAddress, ethAmount)); + if (!receipt.Succeeded()) throw new Exception("Unable to send Eth"); + } + + public decimal GetEthBalance() + { + return GetEthBalance(web3.TransactionManager.Account.Address); + } + + public decimal GetEthBalance(string address) + { + var balance = Time.Wait(web3.Eth.GetBalance.SendRequestAsync(address)); + return Web3.Convert.FromWei(balance.Value); + } + public string GetTokenAddress(string marketplaceAddress) { log.Debug(marketplaceAddress); diff --git a/Tests/AutoBootstrapDistTest.cs b/Tests/AutoBootstrapDistTest.cs index fce68b8..046ff0a 100644 --- a/Tests/AutoBootstrapDistTest.cs +++ b/Tests/AutoBootstrapDistTest.cs @@ -1,13 +1,11 @@ using CodexPlugin; -using DistTestCore; -using DistTestCore.Helpers; using NUnit.Framework; namespace Tests { public class AutoBootstrapDistTest : CodexDistTest { - private readonly List onlineCodexNodes = new List(); + private readonly List onlineCodexNodes = new List(); [SetUp] public void SetUpBootstrapNode() @@ -21,6 +19,6 @@ namespace Tests if (BootstrapNode != null) setup.WithBootstrapNode(BootstrapNode); } - protected IOnlineCodexNode? BootstrapNode { get; private set; } + protected ICodexNode? BootstrapNode { get; private set; } } } diff --git a/Tests/BasicTests/ContinuousSubstitute.cs b/Tests/BasicTests/ContinuousSubstitute.cs index cdcf2d3..5a4b32d 100644 --- a/Tests/BasicTests/ContinuousSubstitute.cs +++ b/Tests/BasicTests/ContinuousSubstitute.cs @@ -21,7 +21,7 @@ namespace Tests.BasicTests .WithBlockTTL(TimeSpan.FromMinutes(2)) .WithStorageQuota(1.GB())); - var nodes = group.Cast().ToArray(); + var nodes = group.Cast().ToArray(); foreach (var node in nodes) { @@ -58,7 +58,7 @@ namespace Tests.BasicTests .WithBlockTTL(TimeSpan.FromMinutes(2)) .WithStorageQuota(1.GB())); - var nodes = group.Cast().ToArray(); + var nodes = group.Cast().ToArray(); var checkTime = DateTime.UtcNow + TimeSpan.FromMinutes(1); var endTime = DateTime.UtcNow + TimeSpan.FromHours(10); @@ -75,7 +75,7 @@ namespace Tests.BasicTests } } - private void CheckRoutingTables(IEnumerable nodes) + private void CheckRoutingTables(IEnumerable nodes) { var all = nodes.ToArray(); var allIds = all.Select(n => n.GetDebugInfo().table.localNode.nodeId).ToArray(); @@ -88,7 +88,7 @@ namespace Tests.BasicTests } } - private string AreAllPresent(IOnlineCodexNode n, string[] allIds) + private string AreAllPresent(ICodexNode n, string[] allIds) { var info = n.GetDebugInfo(); var known = info.table.nodes.Select(n => n.nodeId).ToArray(); @@ -104,7 +104,7 @@ namespace Tests.BasicTests private ByteSize fileSize = 80.MB(); - private void PerformTest(IOnlineCodexNode primary, IOnlineCodexNode secondary) + private void PerformTest(ICodexNode primary, ICodexNode secondary) { ScopedTestFiles(() => { @@ -129,7 +129,7 @@ namespace Tests.BasicTests .WithBlockMaintenanceNumber(10000) .WithStorageQuota(2000.MB())); - var nodes = group.Cast().ToArray(); + var nodes = group.Cast().ToArray(); var endTime = DateTime.UtcNow + TimeSpan.FromHours(24); diff --git a/Tests/BasicTests/ExampleTests.cs b/Tests/BasicTests/ExampleTests.cs index ef519af..a907276 100644 --- a/Tests/BasicTests/ExampleTests.cs +++ b/Tests/BasicTests/ExampleTests.cs @@ -34,7 +34,7 @@ namespace Tests.BasicTests var primary2 = group2[0]; var secondary2 = group2[1]; - var metrics = Ci.GetMetricsFor(primary.MetricsScrapeTarget, primary2.MetricsScrapeTarget); + var metrics = Ci.GetMetricsFor(primary, primary2); primary.ConnectToPeer(secondary); primary2.ConnectToPeer(secondary2); @@ -54,9 +54,9 @@ namespace Tests.BasicTests var node = Ci.SetupCodexNode(s => s.EnableMarketplace(geth, contracts)); - var i = 0; - - //geth.SendEth(node.EthAddress, 10.Eth()); + var myBalance = geth.GetEthBalance(); + geth.SendEth(node, 10.Eth()); + var nodeBalance = geth.GetEthBalance(node); //contracts.MintTestTokens(geth, node.EthAddress, 100.TestTokens()); @@ -64,7 +64,7 @@ namespace Tests.BasicTests //contracts.GetTestTokenBalance(geth, node.EthAddress); - + var i = 0; //var sellerInitialBalance = 234.TestTokens(); diff --git a/Tests/BasicTests/NetworkIsolationTest.cs b/Tests/BasicTests/NetworkIsolationTest.cs index 38e9a49..c6e5491 100644 --- a/Tests/BasicTests/NetworkIsolationTest.cs +++ b/Tests/BasicTests/NetworkIsolationTest.cs @@ -12,7 +12,7 @@ namespace Tests.BasicTests [Ignore("Disabled until a solution is implemented.")] public class NetworkIsolationTest : DistTest { - private IOnlineCodexNode? node = null; + private ICodexNode? node = null; [Test] public void SetUpANodeAndWait() diff --git a/Tests/BasicTests/OneClientTests.cs b/Tests/BasicTests/OneClientTests.cs index 728d718..e878e14 100644 --- a/Tests/BasicTests/OneClientTests.cs +++ b/Tests/BasicTests/OneClientTests.cs @@ -21,14 +21,14 @@ namespace Tests.BasicTests { var primary = Ci.SetupCodexNode(); - primary.BringOffline(); + primary.Stop(); primary = Ci.SetupCodexNode(); PerformOneClientTest(primary); } - private void PerformOneClientTest(IOnlineCodexNode primary) + private void PerformOneClientTest(ICodexNode primary) { var testFile = GenerateTestFile(1.MB()); diff --git a/Tests/BasicTests/TwoClientTests.cs b/Tests/BasicTests/TwoClientTests.cs index 7c34053..5f0db78 100644 --- a/Tests/BasicTests/TwoClientTests.cs +++ b/Tests/BasicTests/TwoClientTests.cs @@ -29,12 +29,12 @@ namespace Tests.BasicTests PerformTwoClientTest(primary, secondary); } - private void PerformTwoClientTest(IOnlineCodexNode primary, IOnlineCodexNode secondary) + private void PerformTwoClientTest(ICodexNode primary, ICodexNode secondary) { PerformTwoClientTest(primary, secondary, 1.MB()); } - private void PerformTwoClientTest(IOnlineCodexNode primary, IOnlineCodexNode secondary, ByteSize size) + private void PerformTwoClientTest(ICodexNode primary, ICodexNode secondary, ByteSize size) { primary.ConnectToPeer(secondary); diff --git a/Tests/CodexDistTest.cs b/Tests/CodexDistTest.cs index 6ecd203..d52fc79 100644 --- a/Tests/CodexDistTest.cs +++ b/Tests/CodexDistTest.cs @@ -6,14 +6,14 @@ namespace Tests { public class CodexDistTest : DistTest { - private readonly List onlineCodexNodes = new List(); + private readonly List onlineCodexNodes = new List(); - public IOnlineCodexNode AddCodex() + public ICodexNode AddCodex() { return AddCodex(s => { }); } - public IOnlineCodexNode AddCodex(Action setup) + public ICodexNode AddCodex(Action setup) { return AddCodex(1, setup)[0]; } @@ -44,7 +44,7 @@ namespace Tests return new PeerDownloadTestHelpers(GetTestLog(), Get().GetFileManager()); } - public IEnumerable GetAllOnlineCodexNodes() + public IEnumerable GetAllOnlineCodexNodes() { return onlineCodexNodes; } diff --git a/Tests/Helpers/FullConnectivityHelper.cs b/Tests/Helpers/FullConnectivityHelper.cs index 419f54d..e0ef335 100644 --- a/Tests/Helpers/FullConnectivityHelper.cs +++ b/Tests/Helpers/FullConnectivityHelper.cs @@ -23,12 +23,12 @@ namespace DistTestCore.Helpers this.implementation = implementation; } - public void AssertFullyConnected(IEnumerable nodes) + public void AssertFullyConnected(IEnumerable nodes) { AssertFullyConnected(nodes.ToArray()); } - private void AssertFullyConnected(IOnlineCodexNode[] nodes) + private void AssertFullyConnected(ICodexNode[] nodes) { Log($"Asserting '{implementation.Description()}' for nodes: '{string.Join(",", nodes.Select(n => n.GetName()))}'..."); var entries = CreateEntries(nodes); @@ -67,7 +67,7 @@ namespace DistTestCore.Helpers Log($"Connections successful:{Nl}{string.Join(Nl, results)}"); } - private Entry[] CreateEntries(IOnlineCodexNode[] nodes) + private Entry[] CreateEntries(ICodexNode[] nodes) { var entries = nodes.Select(n => new Entry(n)).ToArray(); @@ -107,13 +107,13 @@ namespace DistTestCore.Helpers public class Entry { - public Entry(IOnlineCodexNode node) + public Entry(ICodexNode node) { Node = node; Response = node.GetDebugInfo(); } - public IOnlineCodexNode Node { get; } + public ICodexNode Node { get; } public CodexDebugResponse Response { get; } public override string ToString() diff --git a/Tests/Helpers/PeerConnectionTestHelpers.cs b/Tests/Helpers/PeerConnectionTestHelpers.cs index e5f4d83..bde5aeb 100644 --- a/Tests/Helpers/PeerConnectionTestHelpers.cs +++ b/Tests/Helpers/PeerConnectionTestHelpers.cs @@ -13,7 +13,7 @@ namespace DistTestCore.Helpers helper = new FullConnectivityHelper(log, this); } - public void AssertFullyConnected(IEnumerable nodes) + public void AssertFullyConnected(IEnumerable nodes) { helper.AssertFullyConnected(nodes); } diff --git a/Tests/Helpers/PeerDownloadTestHelpers.cs b/Tests/Helpers/PeerDownloadTestHelpers.cs index 3af375d..6ad178f 100644 --- a/Tests/Helpers/PeerDownloadTestHelpers.cs +++ b/Tests/Helpers/PeerDownloadTestHelpers.cs @@ -21,7 +21,7 @@ namespace DistTestCore.Helpers this.fileManager = fileManager; } - public void AssertFullDownloadInterconnectivity(IEnumerable nodes, ByteSize testFileSize) + public void AssertFullDownloadInterconnectivity(IEnumerable nodes, ByteSize testFileSize) { this.testFileSize = testFileSize; helper.AssertFullyConnected(nodes); @@ -62,12 +62,12 @@ namespace DistTestCore.Helpers // Should an exception occur during upload, then this try is inconclusive and we try again next loop. } - private TrackedFile? DownloadFile(IOnlineCodexNode node, ContentId contentId, string label) + private TrackedFile? DownloadFile(ICodexNode node, ContentId contentId, string label) { return node.DownloadContent(contentId, label); } - private TrackedFile GenerateTestFile(IOnlineCodexNode uploader, IOnlineCodexNode downloader) + private TrackedFile GenerateTestFile(ICodexNode uploader, ICodexNode downloader) { var up = uploader.GetName().Replace("<", "").Replace(">", ""); var down = downloader.GetName().Replace("<", "").Replace(">", "");