Can send eth
This commit is contained in:
parent
a20fc6864b
commit
58b1c1e03c
|
@ -14,8 +14,8 @@ namespace CodexContractsPlugin
|
|||
{
|
||||
var config = startupConfig.Get<CodexContractsContainerConfig>();
|
||||
|
||||
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");
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
namespace CodexContractsPlugin
|
||||
{
|
||||
public class TestToken : IComparable<TestToken>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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}");
|
||||
|
|
|
@ -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?
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ using System.Collections;
|
|||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
public interface ICodexNodeGroup : IEnumerable<IOnlineCodexNode>, IManyMetricScrapeTargets
|
||||
public interface ICodexNodeGroup : IEnumerable<ICodexNode>, 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<OnlineCodexNode>();
|
||||
Nodes = Array.Empty<CodexNode>();
|
||||
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<IOnlineCodexNode> GetEnumerator()
|
||||
public IEnumerator<ICodexNode> GetEnumerator()
|
||||
{
|
||||
return Nodes.Cast<IOnlineCodexNode>().GetEnumerator();
|
||||
return Nodes.Cast<ICodexNode>().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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<ICodexSetup> setup)
|
||||
public static ICodexNode SetupCodexNode(this CoreInterface ci, Action<ICodexSetup> setup)
|
||||
{
|
||||
return ci.SetupCodexNodes(1, setup)[0];
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ namespace GethPlugin
|
|||
{
|
||||
public static IGethNode StartGethNode(this CoreInterface ci, Action<IGethSetup> setup)
|
||||
{
|
||||
return Plugin(ci).StartGeth(setup);
|
||||
var p = Plugin(ci);
|
||||
return p.WrapGethContainer(p.StartGeth(setup));
|
||||
}
|
||||
|
||||
private static GethPlugin Plugin(CoreInterface ci)
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
namespace DistTestCore
|
||||
namespace GethPlugin
|
||||
{
|
||||
public class Ether : IComparable<Ether>
|
||||
{
|
||||
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<TestToken>
|
||||
{
|
||||
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)
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<IGethSetup> setup)
|
||||
public IGethStartResult StartGeth(Action<IGethSetup> setup)
|
||||
{
|
||||
var startupConfig = new GethStartupConfig();
|
||||
setup(startupConfig);
|
||||
return starter.StartGeth(startupConfig);
|
||||
}
|
||||
|
||||
//public RunningContainers[] StartCodexNodes(int numberOfNodes, Action<ICodexSetup> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace GethPlugin
|
|||
this.tools = tools;
|
||||
}
|
||||
|
||||
public IGethNode StartGeth(GethStartupConfig gethStartupConfig)
|
||||
public IGethStartResult StartGeth(GethStartupConfig gethStartupConfig)
|
||||
{
|
||||
Log("Starting Geth bootstrap node...");
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -9,7 +9,12 @@ namespace MetricsPlugin
|
|||
int Port { get; }
|
||||
}
|
||||
|
||||
public interface IManyMetricScrapeTargets
|
||||
public interface IHasMetricsScrapeTarget
|
||||
{
|
||||
IMetricsScrapeTarget MetricsScrapeTarget { get; }
|
||||
}
|
||||
|
||||
public interface IHasManyMetricScrapeTargets
|
||||
{
|
||||
IMetricsScrapeTarget[] ScrapeTargets { get; }
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
using CodexPlugin;
|
||||
using DistTestCore;
|
||||
using DistTestCore.Helpers;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Tests
|
||||
{
|
||||
public class AutoBootstrapDistTest : CodexDistTest
|
||||
{
|
||||
private readonly List<IOnlineCodexNode> onlineCodexNodes = new List<IOnlineCodexNode>();
|
||||
private readonly List<ICodexNode> onlineCodexNodes = new List<ICodexNode>();
|
||||
|
||||
[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; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Tests.BasicTests
|
|||
.WithBlockTTL(TimeSpan.FromMinutes(2))
|
||||
.WithStorageQuota(1.GB()));
|
||||
|
||||
var nodes = group.Cast<OnlineCodexNode>().ToArray();
|
||||
var nodes = group.Cast<CodexNode>().ToArray();
|
||||
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ namespace Tests.BasicTests
|
|||
.WithBlockTTL(TimeSpan.FromMinutes(2))
|
||||
.WithStorageQuota(1.GB()));
|
||||
|
||||
var nodes = group.Cast<OnlineCodexNode>().ToArray();
|
||||
var nodes = group.Cast<CodexNode>().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<IOnlineCodexNode> nodes)
|
||||
private void CheckRoutingTables(IEnumerable<ICodexNode> 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<OnlineCodexNode>().ToArray();
|
||||
var nodes = group.Cast<CodexNode>().ToArray();
|
||||
|
||||
var endTime = DateTime.UtcNow + TimeSpan.FromHours(24);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ namespace Tests
|
|||
{
|
||||
public class CodexDistTest : DistTest
|
||||
{
|
||||
private readonly List<IOnlineCodexNode> onlineCodexNodes = new List<IOnlineCodexNode>();
|
||||
private readonly List<ICodexNode> onlineCodexNodes = new List<ICodexNode>();
|
||||
|
||||
public IOnlineCodexNode AddCodex()
|
||||
public ICodexNode AddCodex()
|
||||
{
|
||||
return AddCodex(s => { });
|
||||
}
|
||||
|
||||
public IOnlineCodexNode AddCodex(Action<ICodexSetup> setup)
|
||||
public ICodexNode AddCodex(Action<ICodexSetup> setup)
|
||||
{
|
||||
return AddCodex(1, setup)[0];
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace Tests
|
|||
return new PeerDownloadTestHelpers(GetTestLog(), Get().GetFileManager());
|
||||
}
|
||||
|
||||
public IEnumerable<IOnlineCodexNode> GetAllOnlineCodexNodes()
|
||||
public IEnumerable<ICodexNode> GetAllOnlineCodexNodes()
|
||||
{
|
||||
return onlineCodexNodes;
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ namespace DistTestCore.Helpers
|
|||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes)
|
||||
public void AssertFullyConnected(IEnumerable<ICodexNode> 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()
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace DistTestCore.Helpers
|
|||
helper = new FullConnectivityHelper(log, this);
|
||||
}
|
||||
|
||||
public void AssertFullyConnected(IEnumerable<IOnlineCodexNode> nodes)
|
||||
public void AssertFullyConnected(IEnumerable<ICodexNode> nodes)
|
||||
{
|
||||
helper.AssertFullyConnected(nodes);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace DistTestCore.Helpers
|
|||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
public void AssertFullDownloadInterconnectivity(IEnumerable<IOnlineCodexNode> nodes, ByteSize testFileSize)
|
||||
public void AssertFullDownloadInterconnectivity(IEnumerable<ICodexNode> 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(">", "");
|
||||
|
|
Loading…
Reference in New Issue