cs-codex-dist-tests/Tests/CodexTests/BasicTests/MarketplaceTests.cs

162 lines
6.6 KiB
C#
Raw Normal View History

2024-04-01 09:00:52 +00:00
using CodexContractsPlugin;
using CodexContractsPlugin.Marketplace;
using CodexPlugin;
using GethPlugin;
using NUnit.Framework;
using Utils;
namespace CodexTests.BasicTests
{
[TestFixture]
public class MarketplaceTests : AutoBootstrapDistTest
{
[Test]
2024-04-01 13:31:54 +00:00
public void MarketplaceExample()
2024-04-01 09:00:52 +00:00
{
var hostInitialBalance = 234.TstWei();
var clientInitialBalance = 100000.TstWei();
2024-04-01 13:31:54 +00:00
var fileSize = 10.MB();
2024-04-01 09:00:52 +00:00
var geth = Ci.StartGethNode(s => s.IsMiner().WithName("disttest-geth"));
var contracts = Ci.StartCodexContracts(geth);
var numberOfHosts = 5;
2024-05-09 07:32:48 +00:00
var hosts = StartCodex(numberOfHosts, s => s
.WithName("Host")
.WithLogLevel(CodexLogLevel.Trace, new CodexLogCustomTopics(CodexLogLevel.Error, CodexLogLevel.Error, CodexLogLevel.Warn)
{
ContractClock = CodexLogLevel.Trace,
})
.WithStorageQuota(11.GB())
.EnableMarketplace(geth, contracts, m => m
.WithInitial(10.Eth(), hostInitialBalance)
.AsStorageNode()
.AsValidator()));
2024-04-01 09:00:52 +00:00
var expectedHostBalance = (numberOfHosts * hostInitialBalance.TstWei).TstWei();
foreach (var host in hosts)
{
2024-04-09 08:57:02 +00:00
AssertBalance(contracts, host, Is.EqualTo(expectedHostBalance));
2024-04-01 13:31:54 +00:00
var availability = new StorageAvailability(
totalSpace: 10.GB(),
maxDuration: TimeSpan.FromMinutes(30),
minPriceForTotalSpace: 1.TstWei(),
maxCollateral: 20.TstWei()
);
2024-04-01 13:31:54 +00:00
host.Marketplace.MakeStorageAvailable(availability);
}
2024-04-01 09:00:52 +00:00
var testFile = GenerateTestFile(fileSize);
2024-05-09 07:32:48 +00:00
var client = StartCodex(s => s
2024-04-01 13:31:54 +00:00
.WithName("Client")
2024-04-01 09:00:52 +00:00
.EnableMarketplace(geth, contracts, m => m
2024-04-01 13:31:54 +00:00
.WithInitial(10.Eth(), clientInitialBalance)));
AssertBalance(contracts, client, Is.EqualTo(clientInitialBalance));
2024-04-01 09:00:52 +00:00
2024-04-01 13:31:54 +00:00
var contentId = client.UploadFile(testFile);
2024-04-01 09:00:52 +00:00
var purchase = new StoragePurchaseRequest(contentId)
{
PricePerSlotPerSecond = 2.TstWei(),
RequiredCollateral = 10.TstWei(),
2024-04-01 09:00:52 +00:00
MinRequiredNumberOfNodes = 5,
NodeFailureTolerance = 2,
ProofProbability = 5,
2024-04-01 13:31:54 +00:00
Duration = TimeSpan.FromMinutes(5),
Expiry = TimeSpan.FromMinutes(4)
2024-04-01 09:00:52 +00:00
};
2024-04-01 13:31:54 +00:00
var purchaseContract = client.Marketplace.RequestStorage(purchase);
2024-04-01 09:00:52 +00:00
2024-04-01 13:31:54 +00:00
WaitForAllSlotFilledEvents(contracts, purchase, geth);
2024-04-01 09:00:52 +00:00
2024-04-01 13:31:54 +00:00
purchaseContract.WaitForStorageContractStarted();
2024-04-01 13:31:54 +00:00
var request = GetOnChainStorageRequest(contracts, geth);
AssertStorageRequest(request, purchase, contracts, client);
AssertContractSlot(contracts, request, 0);
2024-04-01 09:00:52 +00:00
purchaseContract.WaitForStorageContractFinished();
2024-04-01 13:31:54 +00:00
AssertBalance(contracts, client, Is.LessThan(clientInitialBalance), "Buyer was not charged for storage.");
Assert.That(contracts.GetRequestState(request), Is.EqualTo(RequestState.Finished));
2024-04-01 09:00:52 +00:00
}
[Test]
public void CanDownloadContentFromContractCid()
{
var fileSize = 10.MB();
var geth = Ci.StartGethNode(s => s.IsMiner().WithName("disttest-geth"));
var contracts = Ci.StartCodexContracts(geth);
var testFile = GenerateTestFile(fileSize);
var client = StartCodex(s => s
.WithName("Client")
.EnableMarketplace(geth, contracts, m => m
.WithInitial(10.Eth(), 10.Tst())));
var uploadCid = client.UploadFile(testFile);
var purchase = new StoragePurchaseRequest(uploadCid)
{
PricePerSlotPerSecond = 2.TstWei(),
RequiredCollateral = 10.TstWei(),
MinRequiredNumberOfNodes = 5,
NodeFailureTolerance = 2,
ProofProbability = 5,
Duration = TimeSpan.FromMinutes(5),
Expiry = TimeSpan.FromMinutes(4)
};
var purchaseContract = client.Marketplace.RequestStorage(purchase);
var contractCid = purchaseContract.ContentId;
Assert.That(uploadCid.Id, Is.Not.EqualTo(contractCid.Id));
2024-06-14 07:05:56 +00:00
// Download both from client.
testFile.AssertIsEqual(client.DownloadContent(uploadCid));
testFile.AssertIsEqual(client.DownloadContent(contractCid));
2024-06-14 07:05:56 +00:00
// Download both from another node.
var downloader = StartCodex(s => s.WithName("Downloader"));
testFile.AssertIsEqual(downloader.DownloadContent(uploadCid));
testFile.AssertIsEqual(downloader.DownloadContent(contractCid));
}
2024-04-01 13:31:54 +00:00
private void WaitForAllSlotFilledEvents(ICodexContracts contracts, StoragePurchaseRequest purchase, IGethNode geth)
2024-04-01 09:00:52 +00:00
{
Time.Retry(() =>
{
2024-04-01 13:31:54 +00:00
var blockRange = geth.ConvertTimeRangeToBlockRange(GetTestRunTimeRange());
2024-04-01 09:22:28 +00:00
var slotFilledEvents = contracts.GetSlotFilledEvents(blockRange);
2024-04-01 09:00:52 +00:00
var msg = $"SlotFilledEvents: {slotFilledEvents.Length} - NumSlots: {purchase.MinRequiredNumberOfNodes}";
Debug(msg);
if (slotFilledEvents.Length != purchase.MinRequiredNumberOfNodes) throw new Exception(msg);
}, purchase.Expiry + TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5), "Checking SlotFilled events");
2024-04-01 09:00:52 +00:00
}
private void AssertStorageRequest(Request request, StoragePurchaseRequest purchase, ICodexContracts contracts, ICodexNode buyer)
{
Assert.That(contracts.GetRequestState(request), Is.EqualTo(RequestState.Started));
Assert.That(request.ClientAddress, Is.EqualTo(buyer.EthAddress));
Assert.That(request.Ask.Slots, Is.EqualTo(purchase.MinRequiredNumberOfNodes));
}
2024-04-01 13:31:54 +00:00
private Request GetOnChainStorageRequest(ICodexContracts contracts, IGethNode geth)
{
var requests = contracts.GetStorageRequests(geth.ConvertTimeRangeToBlockRange(GetTestRunTimeRange()));
Assert.That(requests.Length, Is.EqualTo(1));
return requests.Single();
}
2024-04-01 09:00:52 +00:00
2024-04-01 13:31:54 +00:00
private void AssertContractSlot(ICodexContracts contracts, Request request, int contractSlotIndex)
2024-04-01 09:00:52 +00:00
{
var slotHost = contracts.GetSlotHost(request, contractSlotIndex);
2024-04-01 13:31:54 +00:00
Assert.That(slotHost?.Address, Is.Not.Null);
2024-04-01 09:00:52 +00:00
}
}
}