2025-01-16 11:31:50 +01:00
|
|
|
|
using CodexClient;
|
2025-04-24 12:53:08 +02:00
|
|
|
|
using CodexPlugin;
|
2025-05-30 08:59:43 +02:00
|
|
|
|
using CodexReleaseTests.Utils;
|
2024-11-25 16:10:17 +01:00
|
|
|
|
using NUnit.Framework;
|
|
|
|
|
|
using Utils;
|
2024-11-21 10:03:09 +01:00
|
|
|
|
|
|
|
|
|
|
namespace CodexReleaseTests.MarketTests
|
|
|
|
|
|
{
|
2025-06-02 18:51:36 +02:00
|
|
|
|
[TestFixture(10, 20, 5)]
|
2025-05-30 08:59:43 +02:00
|
|
|
|
public class SequentialContracts : MarketplaceAutoBootstrapDistTest
|
2024-11-21 10:03:09 +01:00
|
|
|
|
{
|
2025-05-30 08:59:43 +02:00
|
|
|
|
public SequentialContracts(int hosts, int slots, int tolerance)
|
2025-04-24 15:34:31 +02:00
|
|
|
|
{
|
|
|
|
|
|
this.hosts = hosts;
|
2025-06-02 13:32:03 +02:00
|
|
|
|
purchaseParams = new PurchaseParams(slots, tolerance, 10.MB());
|
2025-04-24 15:34:31 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private readonly int hosts;
|
2025-06-02 13:32:03 +02:00
|
|
|
|
private readonly PurchaseParams purchaseParams;
|
2024-11-25 16:10:17 +01:00
|
|
|
|
|
2025-04-24 15:34:31 +02:00
|
|
|
|
protected override int NumberOfHosts => hosts;
|
2025-06-02 18:51:36 +02:00
|
|
|
|
protected override int NumberOfClients => 6;
|
2025-06-02 13:32:03 +02:00
|
|
|
|
protected override ByteSize HostAvailabilitySize => purchaseParams.SlotSize.Multiply(100.0);
|
2025-06-06 10:47:54 +02:00
|
|
|
|
protected override TimeSpan HostAvailabilityMaxDuration => GetContractDuration() * 2;
|
2025-01-25 14:07:15 +01:00
|
|
|
|
private readonly TestToken pricePerBytePerSecond = 10.TstWei();
|
2024-11-25 16:10:17 +01:00
|
|
|
|
|
|
|
|
|
|
[Test]
|
2025-04-24 12:53:08 +02:00
|
|
|
|
[Combinatorial]
|
2025-05-30 08:59:43 +02:00
|
|
|
|
public void Sequential(
|
2025-07-11 10:14:09 +02:00
|
|
|
|
[Values(5)] int numGenerations)
|
2024-11-25 16:10:17 +01:00
|
|
|
|
{
|
|
|
|
|
|
var hosts = StartHosts();
|
2025-04-27 12:10:45 +02:00
|
|
|
|
var clients = StartClients();
|
2025-04-24 12:53:08 +02:00
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < numGenerations; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
Log("Generation: " + i);
|
2025-06-02 18:51:36 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Generation(clients, hosts);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Assert.Fail($"Failed at generation {i} with exception {ex}");
|
|
|
|
|
|
}
|
2025-04-24 12:53:08 +02:00
|
|
|
|
}
|
2025-04-24 19:33:34 +02:00
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(TimeSpan.FromSeconds(12.0));
|
2025-04-24 12:53:08 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-27 12:10:45 +02:00
|
|
|
|
private void Generation(ICodexNodeGroup clients, ICodexNodeGroup hosts)
|
2025-04-24 12:53:08 +02:00
|
|
|
|
{
|
2025-04-28 12:20:36 +02:00
|
|
|
|
var requests = All(clients.ToArray(), CreateStorageRequest);
|
2024-11-25 16:10:17 +01:00
|
|
|
|
|
|
|
|
|
|
All(requests, r =>
|
|
|
|
|
|
{
|
|
|
|
|
|
r.WaitForStorageContractSubmitted();
|
|
|
|
|
|
AssertContractIsOnChain(r);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-05-06 20:33:37 +02:00
|
|
|
|
All(requests, WaitForContractStarted);
|
2024-11-25 16:10:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-28 12:20:36 +02:00
|
|
|
|
private void All<T>(T[] items, Action<T> action)
|
2024-11-25 16:10:17 +01:00
|
|
|
|
{
|
2025-04-28 12:20:36 +02:00
|
|
|
|
var tasks = items.Select(r => Task.Run(() => action(r))).ToArray();
|
2025-04-24 12:53:08 +02:00
|
|
|
|
Task.WaitAll(tasks);
|
|
|
|
|
|
foreach(var t in tasks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t.Exception != null) throw t.Exception;
|
|
|
|
|
|
}
|
2024-11-25 16:10:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-28 12:20:36 +02:00
|
|
|
|
private TResult[] All<T, TResult>(T[] items, Func<T, TResult> action)
|
|
|
|
|
|
{
|
|
|
|
|
|
var tasks = items.Select(r => Task.Run(() => action(r))).ToArray();
|
|
|
|
|
|
Task.WaitAll(tasks);
|
|
|
|
|
|
foreach (var t in tasks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (t.Exception != null) throw t.Exception;
|
|
|
|
|
|
}
|
|
|
|
|
|
return tasks.Select(t => t.Result).ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-25 16:10:17 +01:00
|
|
|
|
private IStoragePurchaseContract CreateStorageRequest(ICodexNode client)
|
|
|
|
|
|
{
|
2025-06-02 13:32:03 +02:00
|
|
|
|
var cid = client.UploadFile(GenerateTestFile(purchaseParams.UploadFilesize));
|
2024-11-25 16:10:17 +01:00
|
|
|
|
var config = GetContracts().Deployment.Config;
|
|
|
|
|
|
return client.Marketplace.RequestStorage(new StoragePurchaseRequest(cid)
|
|
|
|
|
|
{
|
|
|
|
|
|
Duration = GetContractDuration(),
|
|
|
|
|
|
Expiry = GetContractExpiry(),
|
2025-06-02 13:32:03 +02:00
|
|
|
|
MinRequiredNumberOfNodes = (uint)purchaseParams.Nodes,
|
|
|
|
|
|
NodeFailureTolerance = (uint)purchaseParams.Tolerance,
|
2025-01-25 14:07:15 +01:00
|
|
|
|
PricePerBytePerSecond = pricePerBytePerSecond,
|
2025-07-11 10:14:09 +02:00
|
|
|
|
ProofProbability = 100000,
|
2025-04-24 15:34:31 +02:00
|
|
|
|
CollateralPerByte = 1.TstWei()
|
2024-11-25 16:10:17 +01:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private TimeSpan GetContractExpiry()
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetContractDuration() / 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private TimeSpan GetContractDuration()
|
|
|
|
|
|
{
|
2025-04-24 19:33:34 +02:00
|
|
|
|
return Get8TimesConfiguredPeriodDuration() * 4;
|
2024-11-25 16:10:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private TimeSpan Get8TimesConfiguredPeriodDuration()
|
|
|
|
|
|
{
|
|
|
|
|
|
var config = GetContracts().Deployment.Config;
|
2025-06-02 13:32:03 +02:00
|
|
|
|
return TimeSpan.FromSeconds(config.Proofs.Period * 8.0);
|
2024-11-25 16:10:17 +01:00
|
|
|
|
}
|
2024-11-21 10:03:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|