Applies faster geth image

This commit is contained in:
benbierens 2023-05-03 10:21:15 +02:00
parent ea0a690862
commit 01c8238311
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
14 changed files with 143 additions and 154 deletions

View File

@ -36,13 +36,8 @@ namespace DistTestCore
var interaction = marketplaceNetwork.StartInteraction(lifecycle.Log); var interaction = marketplaceNetwork.StartInteraction(lifecycle.Log);
var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress; var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress;
foreach (var account in companionNode.Accounts) var accounts = companionNode.Accounts.Select(a => a.Account).ToArray();
{ interaction.MintTestTokens(accounts, marketplaceConfig.InitialTestTokens.Amount, tokenAddress);
interaction.TransferWeiTo(account.Account, marketplaceConfig.InitialEth.Wei);
interaction.MintTestTokens(account.Account, marketplaceConfig.InitialTestTokens.Amount, tokenAddress);
}
interaction.WaitForAllTransactions();
} }
private GethStartResult CreateGethStartResult(MarketplaceNetwork marketplaceNetwork, GethCompanionNodeInfo companionNode) private GethStartResult CreateGethStartResult(MarketplaceNetwork marketplaceNetwork, GethCompanionNodeInfo companionNode)

View File

@ -7,7 +7,7 @@ namespace DistTestCore.Marketplace
#if Arm64 #if Arm64
public const string DockerImage = "emizzle/codex-contracts-deployment:latest"; public const string DockerImage = "emizzle/codex-contracts-deployment:latest";
#else #else
public const string DockerImage = "thatbenbierens/codex-contracts-deployment"; public const string DockerImage = "thatbenbierens/codex-contracts-deployment:nomint";
#endif #endif
public const string MarketplaceAddressFilename = "/usr/app/deployments/codexdisttestnetwork/Marketplace.json"; public const string MarketplaceAddressFilename = "/usr/app/deployments/codexdisttestnetwork/Marketplace.json";
public const string MarketplaceArtifactFilename = "/usr/app/artifacts/contracts/Marketplace.sol/Marketplace.json"; public const string MarketplaceArtifactFilename = "/usr/app/artifacts/contracts/Marketplace.sol/Marketplace.json";

View File

@ -19,13 +19,14 @@ namespace DistTestCore.Marketplace
this.container = container; this.container = container;
} }
public string ExtractAccount(int? orderNumber) public AllGethAccounts ExtractAccounts()
{ {
log.Debug(); log.Debug();
var account = Retry(() => FetchAccount(orderNumber)); var accountsCsv = Retry(() => FetchAccountsCsv());
if (string.IsNullOrEmpty(account)) throw new InvalidOperationException("Unable to fetch account for geth node. Test infra failure."); if (string.IsNullOrEmpty(accountsCsv)) throw new InvalidOperationException("Unable to fetch accounts.csv for geth node. Test infra failure.");
return account; var lines = accountsCsv.Split('\n');
return new AllGethAccounts(lines.Select(ParseLineToAccount).ToArray());
} }
public string ExtractPubKey() public string ExtractPubKey()
@ -37,15 +38,6 @@ namespace DistTestCore.Marketplace
return pubKey; return pubKey;
} }
public string ExtractPrivateKey(int? orderNumber)
{
log.Debug();
var privKey = Retry(() => FetchPrivateKey(orderNumber));
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()
{ {
log.Debug(); log.Debug();
@ -88,14 +80,9 @@ namespace DistTestCore.Marketplace
} }
} }
private string FetchAccount(int? orderNumber) private string FetchAccountsCsv()
{ {
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.GetAccountFilename(orderNumber)); return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.AccountsFilename);
}
private string FetchPrivateKey(int? orderNumber)
{
return workflow.ExecuteCommand(container, "cat", GethContainerRecipe.GetPrivateKeyFilename(orderNumber));
} }
private string FetchMarketplaceAddress() private string FetchMarketplaceAddress()
@ -120,6 +107,15 @@ namespace DistTestCore.Marketplace
workflow.DownloadContainerLog(container, enodeFinder); workflow.DownloadContainerLog(container, enodeFinder);
return enodeFinder.GetPubKey(); return enodeFinder.GetPubKey();
} }
private GethAccount ParseLineToAccount(string l)
{
var tokens = l.Replace("\r", "").Split(',');
if (tokens.Length != 2) throw new InvalidOperationException();
var account = tokens[0];
var privateKey = tokens[1];
return new GethAccount(account, privateKey);
}
} }
public class PubKeyFinder : LogHandler, ILogHandler public class PubKeyFinder : LogHandler, ILogHandler

View File

@ -6,19 +6,19 @@ namespace DistTestCore.Marketplace
{ {
public class GethBootstrapNodeInfo public class GethBootstrapNodeInfo
{ {
public GethBootstrapNodeInfo(RunningContainers runningContainers, string account, string pubKey, string privateKey, Port discoveryPort) public GethBootstrapNodeInfo(RunningContainers runningContainers, AllGethAccounts allAccounts, string pubKey, Port discoveryPort)
{ {
RunningContainers = runningContainers; RunningContainers = runningContainers;
Account = account; AllAccounts = allAccounts;
Account = allAccounts.Accounts[0];
PubKey = pubKey; PubKey = pubKey;
PrivateKey = privateKey;
DiscoveryPort = discoveryPort; DiscoveryPort = discoveryPort;
} }
public RunningContainers RunningContainers { get; } public RunningContainers RunningContainers { get; }
public string Account { get; } public AllGethAccounts AllAccounts { get; }
public GethAccount Account { get; }
public string PubKey { get; } public string PubKey { get; }
public string PrivateKey { get; }
public Port DiscoveryPort { get; } public Port DiscoveryPort { get; }
public NethereumInteraction StartInteraction(BaseLog log) public NethereumInteraction StartInteraction(BaseLog log)
@ -26,10 +26,19 @@ namespace DistTestCore.Marketplace
var ip = RunningContainers.RunningPod.Cluster.IP; var ip = RunningContainers.RunningPod.Cluster.IP;
var port = RunningContainers.Containers[0].ServicePorts[0].Number; var port = RunningContainers.Containers[0].ServicePorts[0].Number;
var account = Account; var account = Account;
var privateKey = PrivateKey;
var creator = new NethereumInteractionCreator(log, ip, port, account, privateKey); var creator = new NethereumInteractionCreator(log, ip, port, account.PrivateKey);
return creator.CreateWorkflow(); return creator.CreateWorkflow();
} }
} }
public class AllGethAccounts
{
public GethAccount[] Accounts { get; }
public AllGethAccounts(GethAccount[] accounts)
{
Accounts = accounts;
}
}
} }

View File

@ -20,20 +20,20 @@ namespace DistTestCore.Marketplace
var bootstrapContainer = containers.Containers[0]; var bootstrapContainer = containers.Containers[0];
var extractor = new ContainerInfoExtractor(lifecycle.Log, workflow, bootstrapContainer); var extractor = new ContainerInfoExtractor(lifecycle.Log, workflow, bootstrapContainer);
var account = extractor.ExtractAccount(null); var accounts = extractor.ExtractAccounts();
var pubKey = extractor.ExtractPubKey(); var pubKey = extractor.ExtractPubKey();
var privateKey = extractor.ExtractPrivateKey(null);
var discoveryPort = bootstrapContainer.Recipe.GetPortByTag(GethContainerRecipe.DiscoveryPortTag); var discoveryPort = bootstrapContainer.Recipe.GetPortByTag(GethContainerRecipe.DiscoveryPortTag);
var result = new GethBootstrapNodeInfo(containers, accounts, pubKey, discoveryPort);
LogEnd($"Geth bootstrap node started with account '{account}'"); LogEnd($"Geth bootstrap node started with account '{result.Account.Account}'");
return new GethBootstrapNodeInfo(containers, account, pubKey, privateKey, discoveryPort); return result;
} }
private StartupConfig CreateBootstrapStartupConfig() private StartupConfig CreateBootstrapStartupConfig()
{ {
var config = new StartupConfig(); var config = new StartupConfig();
config.Add(new GethStartupConfig(true, null!, 0)); config.Add(new GethStartupConfig(true, null!, 0, 0));
return config; return config;
} }
} }

View File

@ -6,30 +6,29 @@ namespace DistTestCore.Marketplace
{ {
public class GethCompanionNodeInfo public class GethCompanionNodeInfo
{ {
public GethCompanionNodeInfo(RunningContainer runningContainer, GethCompanionAccount[] accounts) public GethCompanionNodeInfo(RunningContainer runningContainer, GethAccount[] accounts)
{ {
RunningContainer = runningContainer; RunningContainer = runningContainer;
Accounts = accounts; Accounts = accounts;
} }
public RunningContainer RunningContainer { get; } public RunningContainer RunningContainer { get; }
public GethCompanionAccount[] Accounts { get; } public GethAccount[] Accounts { get; }
public NethereumInteraction StartInteraction(BaseLog log, GethCompanionAccount account) public NethereumInteraction StartInteraction(BaseLog log, GethAccount account)
{ {
var ip = RunningContainer.Pod.Cluster.IP; var ip = RunningContainer.Pod.Cluster.IP;
var port = RunningContainer.ServicePorts[0].Number; var port = RunningContainer.ServicePorts[0].Number;
var accountStr = account.Account;
var privateKey = account.PrivateKey; var privateKey = account.PrivateKey;
var creator = new NethereumInteractionCreator(log, ip, port, accountStr, privateKey); var creator = new NethereumInteractionCreator(log, ip, port, privateKey);
return creator.CreateWorkflow(); return creator.CreateWorkflow();
} }
} }
public class GethCompanionAccount public class GethAccount
{ {
public GethCompanionAccount(string account, string privateKey) public GethAccount(string account, string privateKey)
{ {
Account = account; Account = account;
PrivateKey = privateKey; PrivateKey = privateKey;

View File

@ -5,6 +5,8 @@ namespace DistTestCore.Marketplace
{ {
public class GethCompanionNodeStarter : BaseStarter public class GethCompanionNodeStarter : BaseStarter
{ {
private int companionAccountIndex = 0;
public GethCompanionNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator) public GethCompanionNodeStarter(TestLifecycle lifecycle, WorkflowCreator workflowCreator)
: base(lifecycle, workflowCreator) : base(lifecycle, workflowCreator)
{ {
@ -14,53 +16,43 @@ namespace DistTestCore.Marketplace
{ {
LogStart($"Initializing companion for {codexSetup.NumberOfNodes} Codex nodes."); LogStart($"Initializing companion for {codexSetup.NumberOfNodes} Codex nodes.");
var startupConfig = CreateCompanionNodeStartupConfig(marketplace.Bootstrap, codexSetup.NumberOfNodes); var config = CreateCompanionNodeStartupConfig(marketplace.Bootstrap, codexSetup.NumberOfNodes);
var workflow = workflowCreator.CreateWorkflow(); var workflow = workflowCreator.CreateWorkflow();
var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), startupConfig); var containers = workflow.Start(1, Location.Unspecified, new GethContainerRecipe(), CreateStartupConfig(config));
WaitForAccountCreation(codexSetup.NumberOfNodes);
if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected one Geth companion node to be created. Test infra failure."); if (containers.Containers.Length != 1) throw new InvalidOperationException("Expected one Geth companion node to be created. Test infra failure.");
var container = containers.Containers[0]; var container = containers.Containers[0];
var node = CreateCompanionInfo(workflow, container, codexSetup.NumberOfNodes); var node = CreateCompanionInfo(container, marketplace, config);
EnsureCompanionNodeIsSynced(node, marketplace); EnsureCompanionNodeIsSynced(node, marketplace);
LogEnd($"Initialized one companion node for {codexSetup.NumberOfNodes} Codex nodes. Their accounts: [{string.Join(",", node.Accounts.Select(a => a.Account))}]"); LogEnd($"Initialized one companion node for {codexSetup.NumberOfNodes} Codex nodes. Their accounts: [{string.Join(",", node.Accounts.Select(a => a.Account))}]");
return node; return node;
} }
private void WaitForAccountCreation(int numberOfNodes) private GethCompanionNodeInfo CreateCompanionInfo(RunningContainer container, MarketplaceNetwork marketplace, GethStartupConfig config)
{ {
// We wait proportional to the number of account the node has to create. It takes a few seconds for each one to generate the keys and create the files var accounts = ExtractAccounts(marketplace, config);
// we will be trying to read in 'ExtractAccount', later on in the start-up process.
Time.Sleep(TimeSpan.FromSeconds(4.5 * numberOfNodes));
}
private GethCompanionNodeInfo CreateCompanionInfo(StartupWorkflow workflow, RunningContainer container, int numberOfAccounts)
{
var extractor = new ContainerInfoExtractor(lifecycle.Log, workflow, container);
var accounts = ExtractAccounts(extractor, numberOfAccounts).ToArray();
return new GethCompanionNodeInfo(container, accounts); return new GethCompanionNodeInfo(container, accounts);
} }
private IEnumerable<GethCompanionAccount> ExtractAccounts(ContainerInfoExtractor extractor, int numberOfAccounts) private static GethAccount[] ExtractAccounts(MarketplaceNetwork marketplace, GethStartupConfig config)
{ {
for (int i = 0; i < numberOfAccounts; i++) yield return ExtractAccount(extractor, i + 1); return marketplace.Bootstrap.AllAccounts.Accounts
} .Skip(1 + config.CompanionAccountStartIndex)
.Take(config.NumberOfCompanionAccounts)
private GethCompanionAccount ExtractAccount(ContainerInfoExtractor extractor, int orderNumber) .ToArray();
{
var account = extractor.ExtractAccount(orderNumber);
var privKey = extractor.ExtractPrivateKey(orderNumber);
return new GethCompanionAccount(account, privKey);
} }
private void EnsureCompanionNodeIsSynced(GethCompanionNodeInfo node, MarketplaceNetwork marketplace) private void EnsureCompanionNodeIsSynced(GethCompanionNodeInfo node, MarketplaceNetwork marketplace)
{ {
try try
{ {
var interaction = node.StartInteraction(lifecycle.Log, node.Accounts.First()); Time.WaitUntil(() =>
interaction.EnsureSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi); {
var interaction = node.StartInteraction(lifecycle.Log, node.Accounts.First());
return interaction.IsSynced(marketplace.Marketplace.Address, marketplace.Marketplace.Abi);
}, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(3));
} }
catch (Exception e) catch (Exception e)
{ {
@ -68,10 +60,17 @@ namespace DistTestCore.Marketplace
} }
} }
private StartupConfig CreateCompanionNodeStartupConfig(GethBootstrapNodeInfo bootstrapNode, int numberOfAccounts) private GethStartupConfig CreateCompanionNodeStartupConfig(GethBootstrapNodeInfo bootstrapNode, int numberOfAccounts)
{
var config = new GethStartupConfig(false, bootstrapNode, companionAccountIndex, numberOfAccounts);
companionAccountIndex += numberOfAccounts;
return config;
}
private StartupConfig CreateStartupConfig(GethStartupConfig gethConfig)
{ {
var config = new StartupConfig(); var config = new StartupConfig();
config.Add(new GethStartupConfig(false, bootstrapNode, numberOfAccounts)); config.Add(gethConfig);
return config; return config;
} }
} }

View File

@ -7,23 +7,14 @@ namespace DistTestCore.Marketplace
#if Arm64 #if Arm64
public const string DockerImage = "emizzle/geth-confenv:latest"; public const string DockerImage = "emizzle/geth-confenv:latest";
#else #else
public const string DockerImage = "thatbenbierens/geth-confenv:latest"; public const string DockerImage = "thatbenbierens/geth-confenv:onethousand";
#endif #endif
public const string HttpPortTag = "http_port"; public const string HttpPortTag = "http_port";
public const string DiscoveryPortTag = "disc_port"; public const string DiscoveryPortTag = "disc_port";
private const string defaultArgs = "--ipcdisable --syncmode full"; private const string defaultArgs = "--ipcdisable --syncmode full";
public static string GetAccountFilename(int? orderNumber) public const string AccountsFilename = "accounts.csv";
{
if (orderNumber == null) return "account_string.txt";
return $"account_string_{orderNumber.Value}.txt";
}
public static string GetPrivateKeyFilename(int? orderNumber)
{
if (orderNumber == null) return "private.key";
return $"private_{orderNumber.Value}.key";
}
protected override string Image => DockerImage; protected override string Image => DockerImage;
@ -50,14 +41,17 @@ namespace DistTestCore.Marketplace
private string CreateBootstapArgs(Port discovery) private string CreateBootstapArgs(Port discovery)
{ {
AddEnvVar("IS_BOOTSTRAP", "1"); AddEnvVar("ENABLE_MINER", "1");
UnlockAccounts(0, 1);
var exposedPort = AddExposedPort(tag: HttpPortTag); var exposedPort = AddExposedPort(tag: HttpPortTag);
return $"--http.port {exposedPort.Number} --port {discovery.Number} --discovery.port {discovery.Number} {defaultArgs}"; return $"--http.port {exposedPort.Number} --port {discovery.Number} --discovery.port {discovery.Number} {defaultArgs}";
} }
private string CreateCompanionArgs(Port discovery, GethStartupConfig config) private string CreateCompanionArgs(Port discovery, GethStartupConfig config)
{ {
AddEnvVar("NUMBER_OF_ACCOUNTS", config.NumberOfCompanionAccounts.ToString()); UnlockAccounts(
config.CompanionAccountStartIndex + 1,
config.NumberOfCompanionAccounts);
var port = AddInternalPort(); var port = AddInternalPort();
var authRpc = AddInternalPort(); var authRpc = AddInternalPort();
@ -70,5 +64,15 @@ namespace DistTestCore.Marketplace
return $"--port {port.Number} --discovery.port {discovery.Number} --authrpc.port {authRpc.Number} --http.addr 0.0.0.0 --http.port {httpPort.Number} --ws --ws.addr 0.0.0.0 --ws.port {httpPort.Number} {bootstrapArg} {defaultArgs}"; return $"--port {port.Number} --discovery.port {discovery.Number} --authrpc.port {authRpc.Number} --http.addr 0.0.0.0 --http.port {httpPort.Number} --ws --ws.addr 0.0.0.0 --ws.port {httpPort.Number} {bootstrapArg} {defaultArgs}";
} }
private void UnlockAccounts(int startIndex, int numberOfAccounts)
{
if (startIndex < 0) throw new ArgumentException();
if (numberOfAccounts < 1) throw new ArgumentException();
if (startIndex + numberOfAccounts > 1000) throw new ArgumentException("Out of accounts!");
AddEnvVar("UNLOCK_START_INDEX", startIndex.ToString());
AddEnvVar("UNLOCK_NUMBER", numberOfAccounts.ToString());
}
} }
} }

View File

@ -2,15 +2,17 @@
{ {
public class GethStartupConfig public class GethStartupConfig
{ {
public GethStartupConfig(bool isBootstrapNode, GethBootstrapNodeInfo bootstrapNode, int numberOfCompanionAccounts) public GethStartupConfig(bool isBootstrapNode, GethBootstrapNodeInfo bootstrapNode, int companionAccountStartIndex, int numberOfCompanionAccounts)
{ {
IsBootstrapNode = isBootstrapNode; IsBootstrapNode = isBootstrapNode;
BootstrapNode = bootstrapNode; BootstrapNode = bootstrapNode;
CompanionAccountStartIndex = companionAccountStartIndex;
NumberOfCompanionAccounts = numberOfCompanionAccounts; NumberOfCompanionAccounts = numberOfCompanionAccounts;
} }
public bool IsBootstrapNode { get; } public bool IsBootstrapNode { get; }
public GethBootstrapNodeInfo BootstrapNode { get; } public GethBootstrapNodeInfo BootstrapNode { get; }
public int CompanionAccountStartIndex { get; }
public int NumberOfCompanionAccounts { get; } public int NumberOfCompanionAccounts { get; }
} }
} }

View File

@ -19,10 +19,10 @@ namespace DistTestCore.Marketplace
{ {
private readonly TestLog log; private readonly TestLog log;
private readonly MarketplaceNetwork marketplaceNetwork; private readonly MarketplaceNetwork marketplaceNetwork;
private readonly GethCompanionAccount account; private readonly GethAccount account;
private readonly CodexAccess codexAccess; private readonly CodexAccess codexAccess;
public MarketplaceAccess(TestLog log, MarketplaceNetwork marketplaceNetwork, GethCompanionAccount account, CodexAccess codexAccess) public MarketplaceAccess(TestLog log, MarketplaceNetwork marketplaceNetwork, GethAccount account, CodexAccess codexAccess)
{ {
this.log = log; this.log = log;
this.marketplaceNetwork = marketplaceNetwork; this.marketplaceNetwork = marketplaceNetwork;

View File

@ -33,10 +33,10 @@ namespace DistTestCore.Marketplace
return new MarketplaceAccess(log, marketplaceNetwork, companionNode, access); return new MarketplaceAccess(log, marketplaceNetwork, companionNode, access);
} }
private GethCompanionAccount GetGethCompanionNode(CodexAccess access) private GethAccount GetGethCompanionNode(CodexAccess access)
{ {
var account = access.Container.Recipe.Additionals.Single(a => a is GethCompanionAccount); var account = access.Container.Recipe.Additionals.Single(a => a is GethAccount);
return (GethCompanionAccount)account; return (GethAccount)account;
} }
} }
} }

View File

@ -10,16 +10,13 @@ namespace NethereumWorkflow
{ {
public class NethereumInteraction public class NethereumInteraction
{ {
private readonly List<Task> openTasks = new List<Task>();
private readonly BaseLog log; private readonly BaseLog log;
private readonly Web3 web3; private readonly Web3 web3;
private readonly string rootAccount;
internal NethereumInteraction(BaseLog log, Web3 web3, string rootAccount) internal NethereumInteraction(BaseLog log, Web3 web3)
{ {
this.log = log; this.log = log;
this.web3 = web3; this.web3 = web3;
this.rootAccount = rootAccount;
} }
public string GetTokenAddress(string marketplaceAddress) public string GetTokenAddress(string marketplaceAddress)
@ -31,29 +28,13 @@ namespace NethereumWorkflow
return Time.Wait(handler.QueryAsync<string>(marketplaceAddress, function)); return Time.Wait(handler.QueryAsync<string>(marketplaceAddress, function));
} }
public void TransferWeiTo(string account, decimal amount) public void MintTestTokens(string[] accounts, decimal amount, string tokenAddress)
{ {
log.Debug($"{amount} --> {account}"); if (amount < 1 || accounts.Length < 1) throw new ArgumentException("Invalid arguments for MintTestTokens");
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for AddToBalance");
var value = ToHexBig(amount); var tasks = accounts.Select(a => MintTokens(a, amount, tokenAddress));
var transactionId = Time.Wait(web3.Eth.TransactionManager.SendTransactionAsync(rootAccount, account, value));
openTasks.Add(web3.Eth.TransactionManager.TransactionReceiptService.PollForReceiptAsync(transactionId));
}
public void MintTestTokens(string account, decimal amount, string tokenAddress) Task.WaitAll(tasks.ToArray());
{
log.Debug($"({tokenAddress}) {amount} --> {account}");
if (amount < 1 || string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
var function = new MintTokensFunction
{
Holder = account,
Amount = ToBig(amount)
};
var handler = web3.Eth.GetContractTransactionHandler<MintTokensFunction>();
openTasks.Add(handler.SendRequestAndWaitForReceiptAsync(tokenAddress, function));
} }
public decimal GetBalance(string tokenAddress, string account) public decimal GetBalance(string tokenAddress, string account)
@ -68,48 +49,54 @@ namespace NethereumWorkflow
return ToDecimal(Time.Wait(handler.QueryAsync<BigInteger>(tokenAddress, function))); return ToDecimal(Time.Wait(handler.QueryAsync<BigInteger>(tokenAddress, function)));
} }
public void WaitForAllTransactions() public bool IsSynced(string marketplaceAddress, string marketplaceAbi)
{ {
var tasks = openTasks.ToArray(); try
openTasks.Clear(); {
return IsBlockNumberOK() && IsContractAvailable(marketplaceAddress, marketplaceAbi);
Task.WaitAll(tasks); }
catch
{
return false;
}
} }
public void EnsureSynced(string marketplaceAddress, string marketplaceAbi) private Task MintTokens(string account, decimal amount, string tokenAddress)
{ {
WaitUntilSynced(); log.Debug($"({tokenAddress}) {amount} --> {account}");
WaitForContract(marketplaceAddress, marketplaceAbi); if (string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
var function = new MintTokensFunction
{
Holder = account,
Amount = ToBig(amount)
};
var handler = web3.Eth.GetContractTransactionHandler<MintTokensFunction>();
return handler.SendRequestAndWaitForReceiptAsync(tokenAddress, function);
} }
private void WaitUntilSynced() private bool IsBlockNumberOK()
{ {
log.Debug(); log.Debug();
Time.WaitUntil(() => var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync());
{ var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync());
var sync = Time.Wait(web3.Eth.Syncing.SendRequestAsync()); var numberOfBlocks = ToDecimal(number);
var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync()); return !sync.IsSyncing && numberOfBlocks > 256;
var numberOfBlocks = ToDecimal(number);
return !sync.IsSyncing && numberOfBlocks > 256;
}, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(3));
} }
private void WaitForContract(string marketplaceAddress, string marketplaceAbi) private bool IsContractAvailable(string marketplaceAddress, string marketplaceAbi)
{ {
log.Debug(); log.Debug();
Time.WaitUntil(() => try
{ {
try var contract = web3.Eth.GetContract(marketplaceAbi, marketplaceAddress);
{ return contract != null;
var contract = web3.Eth.GetContract(marketplaceAbi, marketplaceAddress); }
return contract != null; catch
} {
catch return false;
{ }
return false;
}
}, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(3));
} }
private HexBigInteger ToHexBig(decimal amount) private HexBigInteger ToHexBig(decimal amount)

View File

@ -8,21 +8,19 @@ namespace NethereumWorkflow
private readonly BaseLog log; private readonly BaseLog log;
private readonly string ip; private readonly string ip;
private readonly int port; private readonly int port;
private readonly string rootAccount;
private readonly string privateKey; private readonly string privateKey;
public NethereumInteractionCreator(BaseLog log, string ip, int port, string rootAccount, string privateKey) public NethereumInteractionCreator(BaseLog log, string ip, int port, string privateKey)
{ {
this.log = log; this.log = log;
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
this.rootAccount = rootAccount;
this.privateKey = privateKey; this.privateKey = privateKey;
} }
public NethereumInteraction CreateWorkflow() public NethereumInteraction CreateWorkflow()
{ {
return new NethereumInteraction(log, CreateWeb3(), rootAccount); return new NethereumInteraction(log, CreateWeb3());
} }
private Web3 CreateWeb3() private Web3 CreateWeb3()

View File

@ -71,13 +71,13 @@ namespace Tests.BasicTests
requiredCollateral: 10.TestTokens(), requiredCollateral: 10.TestTokens(),
minRequiredNumberOfNodes: 1, minRequiredNumberOfNodes: 1,
proofProbability: 5, proofProbability: 5,
duration: TimeSpan.FromMinutes(2)); duration: TimeSpan.FromMinutes(1));
Time.Sleep(TimeSpan.FromMinutes(1)); Time.Sleep(TimeSpan.FromSeconds(10));
seller.Marketplace.AssertThatBalance(Is.LessThan(sellerInitialBalance), "Collateral was not placed."); seller.Marketplace.AssertThatBalance(Is.LessThan(sellerInitialBalance), "Collateral was not placed.");
Time.Sleep(TimeSpan.FromMinutes(2)); Time.Sleep(TimeSpan.FromMinutes(1));
seller.Marketplace.AssertThatBalance(Is.GreaterThan(sellerInitialBalance), "Seller was not paid for storage."); seller.Marketplace.AssertThatBalance(Is.GreaterThan(sellerInitialBalance), "Seller was not paid for storage.");
buyer.Marketplace.AssertThatBalance(Is.LessThan(buyerInitialBalance), "Buyer was not charged for storage."); buyer.Marketplace.AssertThatBalance(Is.LessThan(buyerInitialBalance), "Buyer was not charged for storage.");