We mint test tokens!

This commit is contained in:
benbierens 2023-04-18 13:22:41 +02:00
parent 9b38447dbe
commit 98f5e481d1
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
13 changed files with 145 additions and 39 deletions

View File

@ -0,0 +1,39 @@
using KubernetesWorkflow;
namespace DistTestCore
{
public class BaseStarter
{
protected readonly TestLifecycle lifecycle;
protected readonly WorkflowCreator workflowCreator;
private Stopwatch? stopwatch;
public BaseStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
{
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
}
protected void LogStart(string msg)
{
Log(msg);
stopwatch = Stopwatch.Begin(lifecycle.Log, GetClassName());
}
protected void LogEnd(string msg)
{
stopwatch!.End(msg);
stopwatch = null;
}
protected void Log(string msg)
{
lifecycle.Log.Log($"{GetClassName} {msg}");
}
private string GetClassName()
{
return GetType().Name;
}
}
}

View File

@ -3,7 +3,7 @@ using KubernetesWorkflow;
namespace DistTestCore namespace DistTestCore
{ {
public class CodexStarter public class CodexStarter // basestarter
{ {
private readonly TestLifecycle lifecycle; private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator; private readonly WorkflowCreator workflowCreator;

View File

@ -3,7 +3,7 @@ using KubernetesWorkflow;
namespace DistTestCore namespace DistTestCore
{ {
public class GethStarter public class GethStarter // basestarter
{ {
private readonly MarketplaceNetworkCache marketplaceNetworkCache; private readonly MarketplaceNetworkCache marketplaceNetworkCache;
private readonly GethCompanionNodeStarter companionNodeStarter; private readonly GethCompanionNodeStarter companionNodeStarter;
@ -36,8 +36,10 @@ namespace DistTestCore
foreach (var node in companionNodes) foreach (var node in companionNodes)
{ {
interaction.TransferTo(node.Account, marketplaceConfig.InitialEth.Wei); interaction.TransferTo(node.Account, marketplaceConfig.InitialEth.Wei);
// wrong level: mintTestTokens? interactions knows nothing about contract details!
//interaction.MintTestTokens(node.Account, marketplaceConfig.InitialTestTokens.Amount); var tokenAddress = interaction.GetTokenAddress(marketplaceNetwork.Marketplace.Address);
interaction.MintTestTokens(node.Account, marketplaceConfig.InitialTestTokens.Amount, tokenAddress);
} }
} }

View File

@ -3,24 +3,22 @@ using Utils;
namespace DistTestCore.Marketplace namespace DistTestCore.Marketplace
{ {
public class CodexContractsStarter public class CodexContractsStarter : BaseStarter
{ {
private const string readyString = "Done! Sleeping indefinitely..."; private const string readyString = "Done! Sleeping indefinitely...";
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;
public CodexContractsStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator) public CodexContractsStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
: base(lifecycle, workflowCreator)
{ {
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
} }
public MarketplaceInfo Start(RunningContainer bootstrapContainer) public MarketplaceInfo Start(RunningContainer bootstrapContainer)
{ {
LogStart("Deploying Codex contracts...");
var workflow = workflowCreator.CreateWorkflow(); var workflow = workflowCreator.CreateWorkflow();
var startupConfig = CreateStartupConfig(bootstrapContainer); var startupConfig = CreateStartupConfig(bootstrapContainer);
lifecycle.Log.Log("Deploying Codex contracts...");
var containers = workflow.Start(1, Location.Unspecified, new CodexContractsContainerRecipe(), startupConfig); var containers = workflow.Start(1, Location.Unspecified, new CodexContractsContainerRecipe(), startupConfig);
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected 1 Codex contracts container to be created. Test infra failure."); if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected 1 Codex contracts container to be created. Test infra failure.");
var container = containers.Containers[0]; var container = containers.Containers[0];
@ -35,7 +33,7 @@ namespace DistTestCore.Marketplace
var extractor = new ContainerInfoExtractor(workflow, container); var extractor = new ContainerInfoExtractor(workflow, container);
var marketplaceAddress = extractor.ExtractMarketplaceAddress(); var marketplaceAddress = extractor.ExtractMarketplaceAddress();
lifecycle.Log.Log("Contracts deployed."); LogEnd("Contracts deployed.");
return new MarketplaceInfo(marketplaceAddress); return new MarketplaceInfo(marketplaceAddress);
} }

View File

@ -39,6 +39,14 @@ namespace DistTestCore.Marketplace
return pubKey; return pubKey;
} }
public string ExtractBootstrapPrivateKey()
{
var privKey = Retry(FetchBootstrapPrivateKey);
if (string.IsNullOrEmpty(privKey)) throw new InvalidOperationException("Unable to fetch private key from geth node. Test infra failure.");
return privKey;
}
public string ExtractMarketplaceAddress() public string ExtractMarketplaceAddress()
{ {
var marketplaceAddress = Retry(FetchMarketplaceAddress); var marketplaceAddress = Retry(FetchMarketplaceAddress);
@ -80,6 +88,11 @@ namespace DistTestCore.Marketplace
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.AccountFilename); return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.AccountFilename);
} }
private string FetchBootstrapPrivateKey()
{
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.BootstrapPrivateKeyFilename);
}
private string FetchMarketplaceAddress() private string FetchMarketplaceAddress()
{ {
var json = workflow.ExecuteCommand(container, "cat", CodexContractsContainerRecipe.MarketplaceAddressFilename); var json = workflow.ExecuteCommand(container, "cat", CodexContractsContainerRecipe.MarketplaceAddressFilename);

View File

@ -4,12 +4,13 @@ namespace DistTestCore.Marketplace
{ {
public class GethBootstrapNodeInfo public class GethBootstrapNodeInfo
{ {
public GethBootstrapNodeInfo(RunningContainers runningContainers, string account, string genesisJsonBase64, string pubKey, Port discoveryPort) public GethBootstrapNodeInfo(RunningContainers runningContainers, string account, string genesisJsonBase64, string pubKey, string privateKey, Port discoveryPort)
{ {
RunningContainers = runningContainers; RunningContainers = runningContainers;
Account = account; Account = account;
GenesisJsonBase64 = genesisJsonBase64; GenesisJsonBase64 = genesisJsonBase64;
PubKey = pubKey; PubKey = pubKey;
PrivateKey = privateKey;
DiscoveryPort = discoveryPort; DiscoveryPort = discoveryPort;
} }
@ -17,6 +18,7 @@ namespace DistTestCore.Marketplace
public string Account { get; } public string Account { get; }
public string GenesisJsonBase64 { get; } public string GenesisJsonBase64 { get; }
public string PubKey { get; } public string PubKey { get; }
public string PrivateKey { get; }
public Port DiscoveryPort { get; } public Port DiscoveryPort { get; }
} }
} }

View File

@ -2,21 +2,18 @@
namespace DistTestCore.Marketplace namespace DistTestCore.Marketplace
{ {
public class GethBootstrapNodeStarter public class GethBootstrapNodeStarter : BaseStarter
{ {
private const string bootstrapGenesisJsonBase64 = "ewogICAgImNvbmZpZyI6IHsKICAgICAgImNoYWluSWQiOiA3ODk5ODgsCiAgICAgICJob21lc3RlYWRCbG9jayI6IDAsCiAgICAgICJlaXAxNTBCbG9jayI6IDAsCiAgICAgICJlaXAxNTVCbG9jayI6IDAsCiAgICAgICJlaXAxNThCbG9jayI6IDAsCiAgICAgICJieXphbnRpdW1CbG9jayI6IDAsCiAgICAgICJjb25zdGFudGlub3BsZUJsb2NrIjogMCwKICAgICAgInBldGVyc2J1cmdCbG9jayI6IDAsCiAgICAgICJpc3RhbmJ1bEJsb2NrIjogMCwKICAgICAgIm11aXJHbGFjaWVyQmxvY2siOiAwLAogICAgICAiYmVybGluQmxvY2siOiAwLAogICAgICAibG9uZG9uQmxvY2siOiAwLAogICAgICAiYXJyb3dHbGFjaWVyQmxvY2siOiAwLAogICAgICAiZ3JheUdsYWNpZXJCbG9jayI6IDAsCiAgICAgICJjbGlxdWUiOiB7CiAgICAgICAgInBlcmlvZCI6IDUsCiAgICAgICAgImVwb2NoIjogMzAwMDAKICAgICAgfQogICAgfSwKICAgICJkaWZmaWN1bHR5IjogIjEiLAogICAgImdhc0xpbWl0IjogIjgwMDAwMDAwMCIsCiAgICAiZXh0cmFkYXRhIjogIjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEFDQ09VTlRfSEVSRTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgImFsbG9jIjogewogICAgICAiMHhBQ0NPVU5UX0hFUkUiOiB7ICJiYWxhbmNlIjogIjUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiIH0KICAgIH0KICB9"; private const string bootstrapGenesisJsonBase64 = "ewogICAgImNvbmZpZyI6IHsKICAgICAgImNoYWluSWQiOiA3ODk5ODgsCiAgICAgICJob21lc3RlYWRCbG9jayI6IDAsCiAgICAgICJlaXAxNTBCbG9jayI6IDAsCiAgICAgICJlaXAxNTVCbG9jayI6IDAsCiAgICAgICJlaXAxNThCbG9jayI6IDAsCiAgICAgICJieXphbnRpdW1CbG9jayI6IDAsCiAgICAgICJjb25zdGFudGlub3BsZUJsb2NrIjogMCwKICAgICAgInBldGVyc2J1cmdCbG9jayI6IDAsCiAgICAgICJpc3RhbmJ1bEJsb2NrIjogMCwKICAgICAgIm11aXJHbGFjaWVyQmxvY2siOiAwLAogICAgICAiYmVybGluQmxvY2siOiAwLAogICAgICAibG9uZG9uQmxvY2siOiAwLAogICAgICAiYXJyb3dHbGFjaWVyQmxvY2siOiAwLAogICAgICAiZ3JheUdsYWNpZXJCbG9jayI6IDAsCiAgICAgICJjbGlxdWUiOiB7CiAgICAgICAgInBlcmlvZCI6IDUsCiAgICAgICAgImVwb2NoIjogMzAwMDAKICAgICAgfQogICAgfSwKICAgICJkaWZmaWN1bHR5IjogIjEiLAogICAgImdhc0xpbWl0IjogIjgwMDAwMDAwMCIsCiAgICAiZXh0cmFkYXRhIjogIjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEFDQ09VTlRfSEVSRTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgImFsbG9jIjogewogICAgICAiMHhBQ0NPVU5UX0hFUkUiOiB7ICJiYWxhbmNlIjogIjUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiIH0KICAgIH0KICB9";
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;
public GethBootstrapNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator) public GethBootstrapNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
: base(lifecycle, workflowCreator)
{ {
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
} }
public GethBootstrapNodeInfo StartGethBootstrapNode() public GethBootstrapNodeInfo StartGethBootstrapNode()
{ {
Log("Starting Geth bootstrap node..."); LogStart("Starting Geth bootstrap node...");
var startupConfig = CreateBootstrapStartupConfig(); var startupConfig = CreateBootstrapStartupConfig();
var workflow = workflowCreator.CreateWorkflow(); var workflow = workflowCreator.CreateWorkflow();
@ -28,11 +25,12 @@ namespace DistTestCore.Marketplace
var account = extractor.ExtractAccount(); var account = extractor.ExtractAccount();
var genesisJsonBase64 = extractor.ExtractGenesisJsonBase64(); var genesisJsonBase64 = extractor.ExtractGenesisJsonBase64();
var pubKey = extractor.ExtractPubKey(); var pubKey = extractor.ExtractPubKey();
var privateKey = extractor.ExtractBootstrapPrivateKey();
var discoveryPort = bootstrapContainer.Recipe.GetPortByTag(GethContainerRecipe.DiscoveryPortTag); var discoveryPort = bootstrapContainer.Recipe.GetPortByTag(GethContainerRecipe.DiscoveryPortTag);
Log($"Geth bootstrap node started with account '{account}'"); LogEnd($"Geth bootstrap node started with account '{account}'");
return new GethBootstrapNodeInfo(containers, account, genesisJsonBase64, pubKey, discoveryPort); return new GethBootstrapNodeInfo(containers, account, genesisJsonBase64, pubKey, privateKey, discoveryPort);
} }
private StartupConfig CreateBootstrapStartupConfig() private StartupConfig CreateBootstrapStartupConfig()
@ -41,10 +39,5 @@ namespace DistTestCore.Marketplace
config.Add(new GethStartupConfig(true, bootstrapGenesisJsonBase64, null!)); config.Add(new GethStartupConfig(true, bootstrapGenesisJsonBase64, null!));
return config; return config;
} }
private void Log(string msg)
{
lifecycle.Log.Log(msg);
}
} }
} }

View File

@ -9,6 +9,7 @@ namespace DistTestCore.Marketplace
public const string DiscoveryPortTag = "disc_port"; public const string DiscoveryPortTag = "disc_port";
public const string AccountFilename = "account_string.txt"; public const string AccountFilename = "account_string.txt";
public const string GenesisFilename = "genesis.json"; public const string GenesisFilename = "genesis.json";
public const string BootstrapPrivateKeyFilename = "bootstrap_private.key";
protected override string Image => DockerImage; protected override string Image => DockerImage;

View File

@ -19,8 +19,9 @@ namespace DistTestCore.Marketplace
var ip = Bootstrap.RunningContainers.RunningPod.Cluster.IP; var ip = Bootstrap.RunningContainers.RunningPod.Cluster.IP;
var port = Bootstrap.RunningContainers.Containers[0].ServicePorts[0].Number; var port = Bootstrap.RunningContainers.Containers[0].ServicePorts[0].Number;
var account = Bootstrap.Account; var account = Bootstrap.Account;
var privateKey = Bootstrap.PrivateKey;
var creator = new NethereumInteractionCreator(log, ip, port, account); var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey);
return creator.CreateWorkflow(); return creator.CreateWorkflow();
} }
} }

View File

@ -5,7 +5,7 @@ using System.Text;
namespace DistTestCore namespace DistTestCore
{ {
public class PrometheusStarter public class PrometheusStarter // basestarter
{ {
private readonly TestLifecycle lifecycle; private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator; private readonly WorkflowCreator workflowCreator;

View File

@ -5,15 +5,32 @@ namespace DistTestCore
{ {
public class Stopwatch public class Stopwatch
{ {
private readonly DateTime start = DateTime.UtcNow;
private readonly BaseLog log;
private readonly string name;
public Stopwatch(BaseLog log, string name)
{
this.log = log;
this.name = name;
}
public static void Measure(BaseLog log, string name, Action action) public static void Measure(BaseLog log, string name, Action action)
{ {
var start = DateTime.UtcNow; var sw = Begin(log, name);
action(); action();
sw.End();
}
public static Stopwatch Begin(BaseLog log, string name)
{
return new Stopwatch(log, name);
}
public void End(string msg = "")
{
var duration = DateTime.UtcNow - start; var duration = DateTime.UtcNow - start;
log.Log($"{name} {msg} ({Time.FormatDuration(duration)})");
log.Log($"{name} ({Time.FormatDuration(duration)})");
} }
} }
} }

View File

@ -1,4 +1,6 @@
using Logging; using Logging;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts;
using Nethereum.Hex.HexTypes; using Nethereum.Hex.HexTypes;
using Nethereum.Web3; using Nethereum.Web3;
using System.Numerics; using System.Numerics;
@ -30,12 +32,28 @@ namespace NethereumWorkflow
Log($"Transferred {amount} to {account}"); Log($"Transferred {amount} to {account}");
} }
public void MintTestTokens(string account, decimal amount) public string GetTokenAddress(string marketplaceAddress)
{
var function = new GetTokenFunction();
var handler = web3.Eth.GetContractQueryHandler<GetTokenFunction>();
var result = Time.Wait(handler.QueryAsync<string>(marketplaceAddress, function));
return result;
}
public void MintTestTokens(string account, decimal amount, string tokenAddress)
{ {
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens"); if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
// - address of token? -> address of marketplace? var function = new MintTokensFunction
// - nethereum do contract call {
Holder = account,
Amount = ToBig(amount)
};
var handler = web3.Eth.GetContractTransactionHandler<MintTokensFunction>();
Time.Wait(handler.SendRequestAndWaitForReceiptAsync(tokenAddress, function));
} }
public decimal GetBalance(string account) public decimal GetBalance(string account)
@ -48,11 +66,16 @@ namespace NethereumWorkflow
private HexBigInteger ToHexBig(decimal amount) private HexBigInteger ToHexBig(decimal amount)
{ {
var bigint = new BigInteger(amount); var bigint = ToBig(amount);
var str = bigint.ToString("X"); var str = bigint.ToString("X");
return new HexBigInteger(str); return new HexBigInteger(str);
} }
private BigInteger ToBig(decimal amount)
{
return new BigInteger(amount);
}
private decimal ToDecimal(HexBigInteger hexBigInteger) private decimal ToDecimal(HexBigInteger hexBigInteger)
{ {
return (decimal)hexBigInteger.Value; return (decimal)hexBigInteger.Value;
@ -63,4 +86,19 @@ namespace NethereumWorkflow
log.Log(msg); log.Log(msg);
} }
} }
[Function("token", "address")]
public class GetTokenFunction : FunctionMessage
{
}
[Function("mint")]
public class MintTokensFunction : FunctionMessage
{
[Parameter("address", "holder", 1)]
public string Holder { get; set; }
[Parameter("uint256", "amount", 2)]
public BigInteger Amount { get; set; }
}
} }

View File

@ -9,13 +9,15 @@ namespace NethereumWorkflow
private readonly string ip; private readonly string ip;
private readonly int port; private readonly int port;
private readonly string rootAccount; private readonly string rootAccount;
private readonly string privateKey;
public NethereumInteractionCreator(TestLog log, string ip, int port, string rootAccount) public NethereumInteractionCreator(TestLog log, string ip, int port, string rootAccount, string privateKey)
{ {
this.log = log; this.log = log;
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
this.rootAccount = rootAccount; this.rootAccount = rootAccount;
this.privateKey = privateKey;
} }
public NethereumInteraction CreateWorkflow() public NethereumInteraction CreateWorkflow()
@ -25,8 +27,8 @@ namespace NethereumWorkflow
private Web3 CreateWeb3() private Web3 CreateWeb3()
{ {
//var bootstrapaccount = new ManagedAccount(bootstrapInfo.Account, "qwerty!@#$%^"); var account = new Nethereum.Web3.Accounts.Account(privateKey);
return new Web3($"http://{ip}:{port}"); return new Web3(account, $"http://{ip}:{port}");
} }
} }
} }