Setting up nethereum library

This commit is contained in:
benbierens 2023-04-14 10:51:35 +02:00
parent 4fd00607df
commit 3d908bab6c
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
21 changed files with 318 additions and 188 deletions

View File

@ -1,7 +1,4 @@
using CodexDistTestCore.Config;
using Nethereum.Web3;
using Nethereum.Web3.Accounts;
using Nethereum.Web3.Accounts.Managed;
using NUnit.Framework;
using System.Numerics;
using System.Text;
@ -22,138 +19,6 @@ namespace CodexDistTestCore.Marketplace
this.k8sManager = k8sManager;
}
public GethCompanionGroup BringOnlineMarketplace(OfflineCodexNodes offline)
{
if (bootstrapInfo == null)
{
BringOnlineBootstrapNode();
}
log.Log($"Initializing companions for {offline.NumberOfNodes} Codex nodes.");
var group = new GethCompanionGroup(companionGroupNumberSource.GetNextNumber(), CreateCompanionContainers(offline));
group.Pod = k8sManager.BringOnlineGethCompanionGroup(bootstrapInfo!, group);
companionGroups.Add(group);
log.Log("Initialized companion nodes.");
return group;
}
private void BringOnlineBootstrapNode()
{
log.Log("Starting Geth bootstrap node...");
var spec = k8sManager.CreateGethBootstrapNodeSpec();
var pod = k8sManager.BringOnlineGethBootstrapNode(spec);
var (account, genesisJson) = ExtractAccountAndGenesisJson(pod);
bootstrapInfo = new GethBootstrapInfo(spec, pod, account, genesisJson);
log.Log($"Geth boothstrap node started.");
}
private GethCompanionNodeContainer[] CreateCompanionContainers(OfflineCodexNodes offline)
{
var numberSource = new NumberSource(8080);
var result = new List<GethCompanionNodeContainer>();
for (var i = 0; i < offline.NumberOfNodes; i++) result.Add(CreateGethNodeContainer(numberSource, i));
return result.ToArray();
}
private GethCompanionNodeContainer CreateGethNodeContainer(NumberSource numberSource, int n)
{
return new GethCompanionNodeContainer(
name: $"geth-node{n}",
apiPort: numberSource.GetNextNumber(),
authRpcPort: numberSource.GetNextNumber(),
rpcPort: numberSource.GetNextNumber(),
containerPortName: $"geth-{n}"
);
}
private readonly K8sCluster k8sCluster = new K8sCluster();
public void AddToBalance(string account, decimal amount)
{
if (amount < 1 || string.IsNullOrEmpty(account)) Assert.Fail("Invalid arguments for AddToBalance");
// call the bootstrap node and convince it to give 'account' 'amount' tokens somehow.
var web3 = CreateWeb3();
//var blockNumber1 = Utils.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync());
//Thread.Sleep(TimeSpan.FromSeconds(5));
//var blockNumber2 = Utils.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync());
//var bootstrapBalance = Utils.Wait(web3.Eth.GetBalance.SendRequestAsync(bootstrapInfo.Account));
var bigint = new BigInteger(amount);
var str = bigint.ToString("X");
var value = new Nethereum.Hex.HexTypes.HexBigInteger(str);
var aaa = Utils.Wait(web3.Eth.TransactionManager.SendTransactionAsync(bootstrapInfo!.Account, account, value));
var receipt = Utils.Wait(web3.Eth.TransactionManager.TransactionReceiptService.PollForReceiptAsync(aaa));
//var receipt = Utils.Wait(web3.Eth.GetEtherTransferService().TransferEtherAndWaitForReceiptAsync(account, amount));
//var targetBalance = Utils.Wait(web3.Eth.GetBalance.SendRequestAsync(account));
}
public decimal GetBalance(string account)
{
var web3 = CreateWeb3();
var bigInt = Utils.Wait(web3.Eth.GetBalance.SendRequestAsync(account));
return (decimal)bigInt.Value;
}
private Web3 CreateWeb3()
{
var ip = k8sCluster.GetIp();
var port = bootstrapInfo!.Spec.ServicePort;
//var bootstrapaccount = new ManagedAccount(bootstrapInfo.Account, "qwerty!@#$%^");
return new Web3($"http://{ip}:{port}");
}
private (string, string) ExtractAccountAndGenesisJson(PodInfo pod)
{
var (account, genesisJson) = FetchAccountAndGenesisJson(pod);
if (string.IsNullOrEmpty(account) || string.IsNullOrEmpty(genesisJson))
{
Thread.Sleep(TimeSpan.FromSeconds(15));
(account, genesisJson) = FetchAccountAndGenesisJson(pod);
}
Assert.That(account, Is.Not.Empty, "Unable to fetch account for geth bootstrap node. Test infra failure.");
Assert.That(genesisJson, Is.Not.Empty, "Unable to fetch genesis-json for geth bootstrap node. Test infra failure.");
var encoded = Convert.ToBase64String(Encoding.ASCII.GetBytes(genesisJson));
log.Log($"Initialized geth bootstrap node with account '{account}'");
return (account, encoded);
}
private (string, string) FetchAccountAndGenesisJson(PodInfo pod)
{
var bootstrapAccount = ExecuteCommand(pod, "cat", GethDockerImage.AccountFilename);
var bootstrapGenesisJson = ExecuteCommand(pod, "cat", GethDockerImage.GenesisFilename);
return (bootstrapAccount, bootstrapGenesisJson);
}
private string ExecuteCommand(PodInfo pod, string command, params string[] arguments)
{
return k8sManager.ExecuteCommand(pod, K8sGethBoostrapSpecs.ContainerName, command, arguments);
}
}
public class GethBootstrapInfo
{
public GethBootstrapInfo(K8sGethBoostrapSpecs spec, PodInfo pod, string account, string genesisJsonBase64)
{
Spec = spec;
Pod = pod;
Account = account;
GenesisJsonBase64 = genesisJsonBase64;
}
public K8sGethBoostrapSpecs Spec { get; }
public PodInfo Pod { get; }
public string Account { get; }
public string GenesisJsonBase64 { get; }
}
}

View File

@ -1,12 +1,4 @@
namespace CodexDistTestCore.Marketplace
{
public class MarketplaceInitialConfig
{
public MarketplaceInitialConfig(int initialBalance)
{
InitialBalance = initialBalance;
}
public int InitialBalance { get; }
}
}

View File

@ -1,4 +1,5 @@
using KubernetesWorkflow;
using DistTestCore.Marketplace;
using KubernetesWorkflow;
namespace DistTestCore.Codex
{
@ -32,6 +33,20 @@ namespace DistTestCore.Codex
AddEnvVar("METRICS_ADDR", "0.0.0.0");
AddInternalPortAndVar("METRICS_PORT", tag: MetricsPortTag);
}
if (config.MarketplaceConfig != null)
{
var gethConfig = startupConfig.Get<GethStartResult>();
var companionNode = gethConfig.CompanionNodes[Index];
// Bootstrap node access from within the cluster:
//var ip = gethConfig.BootstrapNode.RunningContainers.RunningPod.Ip;
//var port = gethConfig.BootstrapNode.RunningContainers.Containers[0].Recipe.GetPortByTag(GethContainerRecipe.HttpPortTag);
//AddEnvVar("ETH_PROVIDER", "todo");
//AddEnvVar("ETH_ACCOUNT", companionNode.Account);
//AddEnvVar("ETH_DEPLOYMENT", "todo");
}
}
}
}

View File

@ -1,4 +1,5 @@
using KubernetesWorkflow;
using DistTestCore.Marketplace;
using KubernetesWorkflow;
namespace DistTestCore.Codex
{
@ -8,8 +9,8 @@ namespace DistTestCore.Codex
public CodexLogLevel? LogLevel { get; set; }
public ByteSize? StorageQuota { get; set; }
public bool MetricsEnabled { get; set; }
public MarketplaceInitialConfig? MarketplaceConfig { get; set; }
//public IOnlineCodexNode? BootstrapNode { get; private set; }
//public MarketplaceInitialConfig? MarketplaceConfig { get; private set; }
}
}

View File

@ -1,4 +1,5 @@
using DistTestCore.Codex;
using DistTestCore.Marketplace;
using DistTestCore.Metrics;
namespace DistTestCore
@ -12,17 +13,20 @@ namespace DistTestCore
{
private readonly TestLifecycle lifecycle;
private readonly IMetricsAccessFactory metricsAccessFactory;
private readonly IMarketplaceAccessFactory marketplaceAccessFactory;
public CodexNodeFactory(TestLifecycle lifecycle, IMetricsAccessFactory metricsAccessFactory)
public CodexNodeFactory(TestLifecycle lifecycle, IMetricsAccessFactory metricsAccessFactory, IMarketplaceAccessFactory marketplaceAccessFactory)
{
this.lifecycle = lifecycle;
this.metricsAccessFactory = metricsAccessFactory;
this.marketplaceAccessFactory = marketplaceAccessFactory;
}
public OnlineCodexNode CreateOnlineCodexNode(CodexAccess access, CodexNodeGroup group)
{
var metricsAccess = metricsAccessFactory.CreateMetricsAccess(access.Container);
return new OnlineCodexNode(lifecycle, access, group, metricsAccess);
var marketplaceAccess = marketplaceAccessFactory.CreateMarketplaceAccess();
return new OnlineCodexNode(lifecycle, access, group, metricsAccess, marketplaceAccess);
}
}
}

View File

@ -1,4 +1,5 @@
using DistTestCore.Codex;
using DistTestCore.Marketplace;
using KubernetesWorkflow;
namespace DistTestCore
@ -10,7 +11,7 @@ namespace DistTestCore
//ICodexStartupConfig WithBootstrapNode(IOnlineCodexNode node);
ICodexSetup WithStorageQuota(ByteSize storageQuota);
ICodexSetup EnableMetrics();
//ICodexSetupConfig EnableMarketplace(int initialBalance);
ICodexSetup EnableMarketplace(int initialBalance);
ICodexNodeGroup BringOnline();
}
@ -61,11 +62,11 @@ namespace DistTestCore
return this;
}
//public ICodexSetupConfig EnableMarketplace(int initialBalance)
//{
// MarketplaceConfig = new MarketplaceInitialConfig(initialBalance);
// return this;
//}
public ICodexSetup EnableMarketplace(int initialBalance)
{
MarketplaceConfig = new MarketplaceInitialConfig(initialBalance);
return this;
}
public string Describe()
{

View File

@ -18,16 +18,21 @@ namespace DistTestCore
public ICodexNodeGroup BringOnline(CodexSetup codexSetup)
{
var something = lifecycle.GethStarter.BringOnlineMarketplaceFor(codexSetup);
Log($"Starting {codexSetup.Describe()}...");
var gethStartResult = lifecycle.GethStarter.BringOnlineMarketplaceFor(codexSetup);
var containers = StartCodexContainers(codexSetup);
var startupConfig = new StartupConfig();
startupConfig.Add(codexSetup);
startupConfig.Add(gethStartResult);
var containers = StartCodexContainers(startupConfig, codexSetup.NumberOfNodes, codexSetup.Location);
var metricAccessFactory = lifecycle.PrometheusStarter.CollectMetricsFor(codexSetup, containers);
var codexNodeFactory = new CodexNodeFactory(lifecycle, metricAccessFactory);
var codexNodeFactory = new CodexNodeFactory(lifecycle, metricAccessFactory, gethStartResult.MarketplaceAccessFactory);
var group = CreateCodexGroup(codexSetup, containers, codexNodeFactory);
Log($"Started at '{group.Containers.RunningPod.Ip}'");
return group;
}
@ -54,15 +59,10 @@ namespace DistTestCore
workflow.DownloadContainerLog(container, logHandler);
}
private RunningContainers StartCodexContainers(CodexSetup codexSetup)
private RunningContainers StartCodexContainers(StartupConfig startupConfig, int numberOfNodes, Location location)
{
Log($"Starting {codexSetup.Describe()}...");
var workflow = CreateWorkflow();
var startupConfig = new StartupConfig();
startupConfig.Add(codexSetup);
return workflow.Start(codexSetup.NumberOfNodes, codexSetup.Location, new CodexContainerRecipe(), startupConfig);
return workflow.Start(numberOfNodes, location, new CodexContainerRecipe(), startupConfig);
}
private CodexNodeGroup CreateCodexGroup(CodexSetup codexSetup, RunningContainers runningContainers, CodexNodeFactory codexNodeFactory)
@ -70,7 +70,6 @@ namespace DistTestCore
var group = new CodexNodeGroup(lifecycle, codexSetup, runningContainers, codexNodeFactory);
RunningGroups.Add(group);
Log($"Started at '{group.Containers.RunningPod.Ip}'");
return group;
}

View File

@ -8,7 +8,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nethereum.Web3" Version="4.14.0" />
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
@ -17,5 +16,6 @@
<ItemGroup>
<ProjectReference Include="..\KubernetesWorkflow\KubernetesWorkflow.csproj" />
<ProjectReference Include="..\Logging\Logging.csproj" />
<ProjectReference Include="..\Nethereum\Nethereum.csproj" />
</ItemGroup>
</Project>

View File

@ -6,23 +6,43 @@ namespace DistTestCore
public class GethStarter
{
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;
private readonly GethBootstrapNodeStarter bootstrapNodeStarter;
private readonly GethCompanionNodeStarter companionNodeStarter;
private GethBootstrapNodeInfo? bootstrapNode;
public GethStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
{
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
bootstrapNodeStarter = new GethBootstrapNodeStarter(lifecycle, workflowCreator);
companionNodeStarter = new GethCompanionNodeStarter(lifecycle, workflowCreator);
}
public object BringOnlineMarketplaceFor(CodexSetup codexSetup)
public GethStartResult BringOnlineMarketplaceFor(CodexSetup codexSetup)
{
if (codexSetup.MarketplaceConfig == null) return CreateMarketplaceUnavailableResult();
EnsureBootstrapNode();
StartCompanionNodes(codexSetup);
return null!;
var companionNodes = StartCompanionNodes(codexSetup);
TransferInitialBalance(codexSetup.MarketplaceConfig.InitialBalance, bootstrapNode, companionNodes);
return new GethStartResult(CreateMarketplaceAccessFactory(), bootstrapNode!, companionNodes);
}
private void TransferInitialBalance(int initialBalance, GethBootstrapNodeInfo? bootstrapNode, GethCompanionNodeInfo[] companionNodes)
{
aaaa
}
private GethStartResult CreateMarketplaceUnavailableResult()
{
return new GethStartResult(new MarketplaceUnavailableAccessFactory(), null!, Array.Empty<GethCompanionNodeInfo>());
}
private IMarketplaceAccessFactory CreateMarketplaceAccessFactory()
{
throw new NotImplementedException();
}
private void EnsureBootstrapNode()
@ -31,14 +51,9 @@ namespace DistTestCore
bootstrapNode = bootstrapNodeStarter.StartGethBootstrapNode();
}
private void StartCompanionNodes(CodexSetup codexSetup)
private GethCompanionNodeInfo[] StartCompanionNodes(CodexSetup codexSetup)
{
throw new NotImplementedException();
}
private void Log(string msg)
{
lifecycle.Log.Log(msg);
return companionNodeStarter.StartCompanionNodesFor(codexSetup, bootstrapNode!);
}
}
}

View File

@ -5,6 +5,7 @@ namespace DistTestCore.Marketplace
public class GethContainerRecipe : ContainerRecipeFactory
{
protected override string Image => "thatbenbierens/geth-confenv:latest";
public const string HttpPortTag = "http_port";
public const string AccountFilename = "account_string.txt";
public const string GenesisFilename = "genesis.json";
@ -30,7 +31,7 @@ namespace DistTestCore.Marketplace
var port = AddInternalPort();
var discovery = AddInternalPort();
var authRpc = AddInternalPort();
var httpPort = AddInternalPort();
var httpPort = AddInternalPort(tag: HttpPortTag);
return $"--port {port.Number} --discovery.port {discovery.Number} --authrpc.port {authRpc.Number} --http.port {httpPort.Number}";
}
}

View File

@ -0,0 +1,16 @@
namespace DistTestCore.Marketplace
{
public class GethStartResult
{
public GethStartResult(IMarketplaceAccessFactory marketplaceAccessFactory, GethBootstrapNodeInfo bootstrapNode, GethCompanionNodeInfo[] companionNodes)
{
MarketplaceAccessFactory = marketplaceAccessFactory;
BootstrapNode = bootstrapNode;
CompanionNodes = companionNodes;
}
public IMarketplaceAccessFactory MarketplaceAccessFactory { get; }
public GethBootstrapNodeInfo BootstrapNode { get; }
public GethCompanionNodeInfo[] CompanionNodes { get; }
}
}

View File

@ -0,0 +1,85 @@
using Logging;
using NUnit.Framework;
using NUnit.Framework.Constraints;
namespace DistTestCore.Marketplace
{
public interface IMarketplaceAccess
{
void MakeStorageAvailable(ByteSize size, int minPricePerBytePerSecond, float maxCollateral);
void RequestStorage(ContentId contentId, int pricePerBytePerSecond, float requiredCollateral, float minRequiredNumberOfNodes);
void AssertThatBalance(IResolveConstraint constraint, string message = "");
decimal GetBalance();
}
public class MarketplaceAccess : IMarketplaceAccess
{
private readonly TestLog log;
private readonly CodexNodeGroup group;
public MarketplaceAccess(TestLog log, CodexNodeGroup group)
{
this.log = log;
this.group = group;
}
public void Initialize()
{
EnsureAccount();
marketplaceController.AddToBalance(container.Account, group.Origin.MarketplaceConfig!.InitialBalance);
log.Log($"Initialized Geth companion node with account '{container.Account}' and initial balance {group.Origin.MarketplaceConfig!.InitialBalance}");
}
public void RequestStorage(ContentId contentId, int pricePerBytePerSecond, float requiredCollateral, float minRequiredNumberOfNodes)
{
throw new NotImplementedException();
}
public void MakeStorageAvailable(ByteSize size, int minPricePerBytePerSecond, float maxCollateral)
{
throw new NotImplementedException();
}
public void AssertThatBalance(IResolveConstraint constraint, string message = "")
{
throw new NotImplementedException();
}
public decimal GetBalance()
{
return marketplaceController.GetBalance(container.Account);
}
}
public class MarketplaceUnavailable : IMarketplaceAccess
{
public void RequestStorage(ContentId contentId, int pricePerBytePerSecond, float requiredCollateral, float minRequiredNumberOfNodes)
{
Unavailable();
}
public void MakeStorageAvailable(ByteSize size, int minPricePerBytePerSecond, float maxCollateral)
{
Unavailable();
}
public void AssertThatBalance(IResolveConstraint constraint, string message = "")
{
Unavailable();
}
public decimal GetBalance()
{
Unavailable();
return 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();
}
}
}

View File

@ -0,0 +1,24 @@
namespace DistTestCore.Marketplace
{
public interface IMarketplaceAccessFactory
{
IMarketplaceAccess CreateMarketplaceAccess();
}
public class MarketplaceUnavailableAccessFactory : IMarketplaceAccessFactory
{
public IMarketplaceAccess CreateMarketplaceAccess()
{
return new MarketplaceUnavailable();
}
}
public class GethMarketplaceAccessFactory : IMarketplaceAccessFactory
{
public IMarketplaceAccess CreateMarketplaceAccess()
{
return new MarketplaceAccess(query, codexContainer);
}
}
}

View File

@ -0,0 +1,12 @@
namespace DistTestCore.Marketplace
{
public class MarketplaceInitialConfig
{
public MarketplaceInitialConfig(int initialBalance)
{
InitialBalance = initialBalance;
}
public int InitialBalance { get; }
}
}

View File

@ -1,5 +1,6 @@
using DistTestCore.Codex;
using DistTestCore.Logs;
using DistTestCore.Marketplace;
using DistTestCore.Metrics;
using NUnit.Framework;
@ -13,7 +14,7 @@ namespace DistTestCore
void ConnectToPeer(IOnlineCodexNode node);
ICodexNodeLog DownloadLog();
IMetricsAccess Metrics { get; }
//IMarketplaceAccess Marketplace { get; }
IMarketplaceAccess Marketplace { get; }
}
public class OnlineCodexNode : IOnlineCodexNode
@ -22,17 +23,19 @@ namespace DistTestCore
private const string UploadFailedMessage = "Unable to store block";
private readonly TestLifecycle lifecycle;
public OnlineCodexNode(TestLifecycle lifecycle, CodexAccess codexAccess, CodexNodeGroup group, IMetricsAccess metricsAccess)
public OnlineCodexNode(TestLifecycle lifecycle, CodexAccess codexAccess, CodexNodeGroup group, IMetricsAccess metricsAccess, IMarketplaceAccess marketplaceAccess)
{
this.lifecycle = lifecycle;
CodexAccess = codexAccess;
Group = group;
Metrics = metricsAccess;
Marketplace = marketplaceAccess;
}
public CodexAccess CodexAccess { get; }
public CodexNodeGroup Group { get; }
public IMetricsAccess Metrics { get; }
public IMarketplaceAccess Marketplace { get; }
public string GetName()
{

View File

@ -7,10 +7,11 @@
private readonly List<EnvVar> envVars = new List<EnvVar>();
private RecipeComponentFactory factory = null!;
public ContainerRecipe CreateRecipe(int containerNumber, RecipeComponentFactory factory, StartupConfig config)
public ContainerRecipe CreateRecipe(int index, int containerNumber, RecipeComponentFactory factory, StartupConfig config)
{
this.factory = factory;
ContainerNumber = containerNumber;
Index = index;
Initialize(config);
@ -26,6 +27,7 @@
protected abstract string Image { get; }
protected int ContainerNumber { get; private set; } = 0;
protected int Index { get; private set; } = 0;
protected abstract void Initialize(StartupConfig config);
protected Port AddExposedPort(string tag = "")

View File

@ -68,7 +68,7 @@
var result = new List<ContainerRecipe>();
for (var i = 0; i < numberOfContainers; i++)
{
result.Add(recipeFactory.CreateRecipe(numberSource.GetContainerNumber(), componentFactory, startupConfig));
result.Add(recipeFactory.CreateRecipe(i ,numberSource.GetContainerNumber(), componentFactory, startupConfig));
}
return result.ToArray();

View File

@ -0,0 +1,41 @@
using Nethereum.Hex.HexTypes;
using Nethereum.Web3;
using System.Numerics;
using Utils;
namespace NethereumWorkflow
{
public class NethereumWorkflow
{
private readonly Web3 web3;
private readonly string rootAccount;
internal NethereumWorkflow(Web3 web3, string rootAccount)
{
this.web3 = web3;
this.rootAccount = rootAccount;
}
public void AddToBalance(string account, decimal amount)
{
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance");
var value = ToHexBig(amount);
var transactionId = Time.Wait(web3.Eth.TransactionManager.SendTransactionAsync(rootAccount, account, value));
Time.Wait(web3.Eth.TransactionManager.TransactionReceiptService.PollForReceiptAsync(transactionId));
}
public decimal GetBalance(string account)
{
var bigInt = Time.Wait(web3.Eth.GetBalance.SendRequestAsync(account));
return (decimal)bigInt.Value;
}
private HexBigInteger ToHexBig(decimal amount)
{
var bigint = new BigInteger(amount);
var str = bigint.ToString("X");
return new HexBigInteger(str);
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>NethereumWorkflow</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Nethereum.Web3" Version="4.14.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Logging\Logging.csproj" />
<ProjectReference Include="..\Utils\Utils.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,29 @@
using Nethereum.Web3;
namespace NethereumWorkflow
{
public class NethereumWorkflowCreator
{
private readonly string ip;
private readonly int port;
private readonly string rootAccount;
public NethereumWorkflowCreator(string ip, int port, string rootAccount)
{
this.ip = ip;
this.port = port;
this.rootAccount = rootAccount;
}
public NethereumWorkflow CreateWorkflow()
{
return new NethereumWorkflow(CreateWeb3(), rootAccount);
}
private Web3 CreateWeb3()
{
//var bootstrapaccount = new ManagedAccount(bootstrapInfo.Account, "qwerty!@#$%^");
return new Web3($"http://{ip}:{port}");
}
}
}

View File

@ -9,13 +9,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsLong", "LongTests\Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CodexDistTestCore", "CodexDistTestCore\CodexDistTestCore.csproj", "{19306DE1-CEE5-4F7B-AA5D-FD91926D853D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistTestCore", "DistTestCore\DistTestCore.csproj", "{47F31305-6E68-4827-8E39-7B41DAA1CE7A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistTestCore", "DistTestCore\DistTestCore.csproj", "{47F31305-6E68-4827-8E39-7B41DAA1CE7A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KubernetesWorkflow", "KubernetesWorkflow\KubernetesWorkflow.csproj", "{359123AA-3D9B-4442-80F4-19E32E3EC9EA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KubernetesWorkflow", "KubernetesWorkflow\KubernetesWorkflow.csproj", "{359123AA-3D9B-4442-80F4-19E32E3EC9EA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils.csproj", "{957DE3B8-9571-450A-8609-B267DCA8727C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utils", "Utils\Utils.csproj", "{957DE3B8-9571-450A-8609-B267DCA8727C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logging", "Logging\Logging.csproj", "{8481A4A6-4BDD-41B0-A3EB-EF53F7BD40D1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Logging", "Logging\Logging.csproj", "{8481A4A6-4BDD-41B0-A3EB-EF53F7BD40D1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum", "Nethereum\Nethereum.csproj", "{D6C3555E-D52D-4993-A87B-71AB650398FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -51,6 +53,10 @@ Global
{8481A4A6-4BDD-41B0-A3EB-EF53F7BD40D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8481A4A6-4BDD-41B0-A3EB-EF53F7BD40D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8481A4A6-4BDD-41B0-A3EB-EF53F7BD40D1}.Release|Any CPU.Build.0 = Release|Any CPU
{D6C3555E-D52D-4993-A87B-71AB650398FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D6C3555E-D52D-4993-A87B-71AB650398FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D6C3555E-D52D-4993-A87B-71AB650398FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D6C3555E-D52D-4993-A87B-71AB650398FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE