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
{
public class CodexStarter
public class CodexStarter // basestarter
{
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;

View File

@ -3,7 +3,7 @@ using KubernetesWorkflow;
namespace DistTestCore
{
public class GethStarter
public class GethStarter // basestarter
{
private readonly MarketplaceNetworkCache marketplaceNetworkCache;
private readonly GethCompanionNodeStarter companionNodeStarter;
@ -36,8 +36,10 @@ namespace DistTestCore
foreach (var node in companionNodes)
{
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
{
public class CodexContractsStarter
public class CodexContractsStarter : BaseStarter
{
private const string readyString = "Done! Sleeping indefinitely...";
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;
public CodexContractsStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
: base(lifecycle, workflowCreator)
{
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
}
public MarketplaceInfo Start(RunningContainer bootstrapContainer)
{
LogStart("Deploying Codex contracts...");
var workflow = workflowCreator.CreateWorkflow();
var startupConfig = CreateStartupConfig(bootstrapContainer);
lifecycle.Log.Log("Deploying Codex contracts...");
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.");
var container = containers.Containers[0];
@ -35,7 +33,7 @@ namespace DistTestCore.Marketplace
var extractor = new ContainerInfoExtractor(workflow, container);
var marketplaceAddress = extractor.ExtractMarketplaceAddress();
lifecycle.Log.Log("Contracts deployed.");
LogEnd("Contracts deployed.");
return new MarketplaceInfo(marketplaceAddress);
}

View File

@ -39,6 +39,14 @@ namespace DistTestCore.Marketplace
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()
{
var marketplaceAddress = Retry(FetchMarketplaceAddress);
@ -80,6 +88,11 @@ namespace DistTestCore.Marketplace
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.AccountFilename);
}
private string FetchBootstrapPrivateKey()
{
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.BootstrapPrivateKeyFilename);
}
private string FetchMarketplaceAddress()
{
var json = workflow.ExecuteCommand(container, "cat", CodexContractsContainerRecipe.MarketplaceAddressFilename);

View File

@ -4,12 +4,13 @@ namespace DistTestCore.Marketplace
{
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;
Account = account;
GenesisJsonBase64 = genesisJsonBase64;
PubKey = pubKey;
PrivateKey = privateKey;
DiscoveryPort = discoveryPort;
}
@ -17,6 +18,7 @@ namespace DistTestCore.Marketplace
public string Account { get; }
public string GenesisJsonBase64 { get; }
public string PubKey { get; }
public string PrivateKey { get; }
public Port DiscoveryPort { get; }
}
}

View File

@ -2,21 +2,18 @@
namespace DistTestCore.Marketplace
{
public class GethBootstrapNodeStarter
public class GethBootstrapNodeStarter : BaseStarter
{
private const string bootstrapGenesisJsonBase64 = "ewogICAgImNvbmZpZyI6IHsKICAgICAgImNoYWluSWQiOiA3ODk5ODgsCiAgICAgICJob21lc3RlYWRCbG9jayI6IDAsCiAgICAgICJlaXAxNTBCbG9jayI6IDAsCiAgICAgICJlaXAxNTVCbG9jayI6IDAsCiAgICAgICJlaXAxNThCbG9jayI6IDAsCiAgICAgICJieXphbnRpdW1CbG9jayI6IDAsCiAgICAgICJjb25zdGFudGlub3BsZUJsb2NrIjogMCwKICAgICAgInBldGVyc2J1cmdCbG9jayI6IDAsCiAgICAgICJpc3RhbmJ1bEJsb2NrIjogMCwKICAgICAgIm11aXJHbGFjaWVyQmxvY2siOiAwLAogICAgICAiYmVybGluQmxvY2siOiAwLAogICAgICAibG9uZG9uQmxvY2siOiAwLAogICAgICAiYXJyb3dHbGFjaWVyQmxvY2siOiAwLAogICAgICAiZ3JheUdsYWNpZXJCbG9jayI6IDAsCiAgICAgICJjbGlxdWUiOiB7CiAgICAgICAgInBlcmlvZCI6IDUsCiAgICAgICAgImVwb2NoIjogMzAwMDAKICAgICAgfQogICAgfSwKICAgICJkaWZmaWN1bHR5IjogIjEiLAogICAgImdhc0xpbWl0IjogIjgwMDAwMDAwMCIsCiAgICAiZXh0cmFkYXRhIjogIjB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMEFDQ09VTlRfSEVSRTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgImFsbG9jIjogewogICAgICAiMHhBQ0NPVU5UX0hFUkUiOiB7ICJiYWxhbmNlIjogIjUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiIH0KICAgIH0KICB9";
private readonly TestLifecycle lifecycle;
private readonly WorkflowCreator workflowCreator;
public GethBootstrapNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
: base(lifecycle, workflowCreator)
{
this.lifecycle = lifecycle;
this.workflowCreator = workflowCreator;
}
public GethBootstrapNodeInfo StartGethBootstrapNode()
{
Log("Starting Geth bootstrap node...");
LogStart("Starting Geth bootstrap node...");
var startupConfig = CreateBootstrapStartupConfig();
var workflow = workflowCreator.CreateWorkflow();
@ -28,11 +25,12 @@ namespace DistTestCore.Marketplace
var account = extractor.ExtractAccount();
var genesisJsonBase64 = extractor.ExtractGenesisJsonBase64();
var pubKey = extractor.ExtractPubKey();
var privateKey = extractor.ExtractBootstrapPrivateKey();
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()
@ -41,10 +39,5 @@ namespace DistTestCore.Marketplace
config.Add(new GethStartupConfig(true, bootstrapGenesisJsonBase64, null!));
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 AccountFilename = "account_string.txt";
public const string GenesisFilename = "genesis.json";
public const string BootstrapPrivateKeyFilename = "bootstrap_private.key";
protected override string Image => DockerImage;

View File

@ -19,8 +19,9 @@ namespace DistTestCore.Marketplace
var ip = Bootstrap.RunningContainers.RunningPod.Cluster.IP;
var port = Bootstrap.RunningContainers.Containers[0].ServicePorts[0].Number;
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();
}
}

View File

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

View File

@ -5,15 +5,32 @@ namespace DistTestCore
{
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)
{
var start = DateTime.UtcNow;
var sw = Begin(log, name);
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;
log.Log($"{name} ({Time.FormatDuration(duration)})");
log.Log($"{name} {msg} ({Time.FormatDuration(duration)})");
}
}
}

View File

@ -1,4 +1,6 @@
using Logging;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts;
using Nethereum.Hex.HexTypes;
using Nethereum.Web3;
using System.Numerics;
@ -30,12 +32,28 @@ namespace NethereumWorkflow
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");
// - address of token? -> address of marketplace?
// - nethereum do contract call
var function = new MintTokensFunction
{
Holder = account,
Amount = ToBig(amount)
};
var handler = web3.Eth.GetContractTransactionHandler<MintTokensFunction>();
Time.Wait(handler.SendRequestAndWaitForReceiptAsync(tokenAddress, function));
}
public decimal GetBalance(string account)
@ -48,11 +66,16 @@ namespace NethereumWorkflow
private HexBigInteger ToHexBig(decimal amount)
{
var bigint = new BigInteger(amount);
var bigint = ToBig(amount);
var str = bigint.ToString("X");
return new HexBigInteger(str);
}
private BigInteger ToBig(decimal amount)
{
return new BigInteger(amount);
}
private decimal ToDecimal(HexBigInteger hexBigInteger)
{
return (decimal)hexBigInteger.Value;
@ -63,4 +86,19 @@ namespace NethereumWorkflow
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 int port;
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.ip = ip;
this.port = port;
this.rootAccount = rootAccount;
this.privateKey = privateKey;
}
public NethereumInteraction CreateWorkflow()
@ -25,8 +27,8 @@ namespace NethereumWorkflow
private Web3 CreateWeb3()
{
//var bootstrapaccount = new ManagedAccount(bootstrapInfo.Account, "qwerty!@#$%^");
return new Web3($"http://{ip}:{port}");
var account = new Nethereum.Web3.Accounts.Account(privateKey);
return new Web3(account, $"http://{ip}:{port}");
}
}
}