wip: withdraw funds

This commit is contained in:
benbierens 2024-11-22 16:09:18 +01:00
parent e7a59de207
commit d032b77abe
No known key found for this signature in database
GPG Key ID: 877D2C2E09A22F3A
4 changed files with 115 additions and 52 deletions

View File

@ -2,6 +2,7 @@
using GethPlugin;
using Logging;
using Nethereum.ABI;
using Nethereum.Hex.HexConvertors.Extensions;
using Nethereum.Util;
using NethereumWorkflow;
using Newtonsoft.Json;
@ -24,6 +25,7 @@ namespace CodexContractsPlugin
ICodexContractsEvents GetEvents(BlockInterval blockInterval);
EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex);
RequestState GetRequestState(Request request);
void WithdrawFunds(string purchaseId, EthAddress address);
}
[JsonConverter(typeof(StringEnumConverter))]
@ -114,6 +116,26 @@ namespace CodexContractsPlugin
return gethNode.Call<RequestStateFunction, RequestState>(Deployment.MarketplaceAddress, func);
}
public void WithdrawFunds(string purchaseId, EthAddress address)
{
try
{
log.Log("withdrawing funds....");
var func = new WithdrawFundsFunction
{
RequestId = purchaseId.HexToByteArray(),
FromAddress = address.Address
};
var response = gethNode.Call<WithdrawFundsFunction, string>(Deployment.MarketplaceAddress, func);
log.Log("got response: " + response);
}
catch (Exception ex)
{
log.Log("Got exception: " + ex);
}
}
private ContractInteractions StartInteraction()
{
return new ContractInteractions(log, gethNode);

View File

@ -1,7 +1,5 @@
using CodexContractsPlugin;
using CodexOpenApi;
using Logging;
using System.Data;
using Utils;
namespace CodexPlugin

View File

@ -9,30 +9,46 @@ namespace CodexReleaseTests.MarketTests
[TestFixture]
public class ContractSuccessfulTest : MarketplaceAutoBootstrapDistTest
{
private const int NumberOfHosts = 4;
private const int FilesizeMb = 10;
private const int PricePerSlotPerSecondTSTWei = 10;
protected override int NumberOfHosts => 4;
protected override int NumberOfClients => 1;
protected override ByteSize HostAvailabilitySize => (5 * FilesizeMb).MB();
protected override TimeSpan HostAvailabilityMaxDuration => GetHostAvailabilityDuration();
[Test]
public void ContractSuccessful()
{
var hosts = StartHosts();
var client = StartCodex(s => s.WithName("client"));
var client = StartClients().Single();
var contract = CreateStorageRequest(client);
var request = CreateStorageRequest(client);
contract.WaitForStorageContractSubmitted();
AssertContractIsOnChain(contract);
request.WaitForStorageContractSubmitted();
AssertContractIsOnChain(request);
contract.WaitForStorageContractStarted();
var slotFills = AssertContractSlotsAreFilledByHosts(contract, hosts);
request.WaitForStorageContractStarted();
var slotFills = AssertContractSlotsAreFilledByHosts(request, hosts);
contract.WaitForStorageContractFinished();
AssertClientHasPaidForContract(client, contract);
AssertHostsWerePaidForContract(contract, hosts, slotFills);
request.WaitForStorageContractFinished();
//EveryoneWithdrawsFunds(hosts, client);
GetContracts().WithdrawFunds(request.PurchaseId, client.EthAddress);
foreach (var host in hosts)
GetContracts().WithdrawFunds(request.PurchaseId, host.EthAddress);
AssertClientHasPaidForContract(client, request);
AssertHostsWerePaidForContract(request, hosts, slotFills);
AssertHostsCollateralsAreUnchanged(hosts);
}
//private void EveryoneWithdrawsFunds(ICodexNodeGroup hosts, ICodexNode client)
//{
// foreach (var host in hosts) host.Marketplace.WithdrawFunds();
// client.Marketplace.WithdrawFunds();
//}
private void AssertContractIsOnChain(IStoragePurchaseContract contract)
{
AssertOnChainEvents(events =>
@ -71,18 +87,7 @@ namespace CodexReleaseTests.MarketTests
var balance = GetContracts().GetTestTokenBalance(client);
var expectedBalance = StartingBalanceTST.Tst() - GetContractTotalCost();
Assert.That(balance, Is.EqualTo(expectedBalance));
}
private TestToken GetContractTotalCost()
{
return GetContractCostPerSlot() * NumberOfHosts;
}
private TestToken GetContractCostPerSlot()
{
var duration = GetContractDuration();
return PricePerSlotPerSecondTSTWei.TstWei() * ((int)duration.TotalSeconds);
Assert.That(balance, Is.EqualTo(expectedBalance), "Client balance incorrect.");
}
private void AssertHostsWerePaidForContract(IStoragePurchaseContract contract, ICodexNodeGroup hosts, SlotFill[] fills)
@ -97,7 +102,7 @@ namespace CodexReleaseTests.MarketTests
foreach (var pair in expectedBalances)
{
var balance = GetContracts().GetTestTokenBalance(pair.Key);
Assert.That(balance, Is.EqualTo(pair.Value));
Assert.That(balance, Is.EqualTo(pair.Value), "Host was not paid for storage.");
}
}
@ -127,36 +132,40 @@ namespace CodexReleaseTests.MarketTests
return client.Marketplace.RequestStorage(new StoragePurchaseRequest(cid)
{
Duration = GetContractDuration(),
Expiry = TimeSpan.FromSeconds(((double)config.Proofs.Period) * 1.0),
MinRequiredNumberOfNodes = NumberOfHosts,
NodeFailureTolerance = NumberOfHosts / 2,
Expiry = GetContractExpiry(),
MinRequiredNumberOfNodes = (uint)NumberOfHosts,
NodeFailureTolerance = (uint)(NumberOfHosts / 2),
PricePerSlotPerSecond = PricePerSlotPerSecondTSTWei.TstWei(),
ProofProbability = 20,
RequiredCollateral = 1.Tst()
});
}
private TimeSpan GetContractDuration()
private TestToken GetContractTotalCost()
{
var config = GetContracts().Deployment.Config;
return TimeSpan.FromSeconds(((double)config.Proofs.Period) * 2.0);
return GetContractCostPerSlot() * NumberOfHosts;
}
private ICodexNodeGroup StartHosts()
private TestToken GetContractCostPerSlot()
{
var hosts = StartCodex(NumberOfHosts, s => s.WithName("host"));
var duration = GetContractDuration();
return PricePerSlotPerSecondTSTWei.TstWei() * ((int)duration.TotalSeconds);
}
private TimeSpan GetContractExpiry()
{
return GetContractDuration() / 2;
}
private TimeSpan GetContractDuration()
{
return GetHostAvailabilityDuration() / 2;
}
private TimeSpan GetHostAvailabilityDuration()
{
var config = GetContracts().Deployment.Config;
foreach (var host in hosts)
{
host.Marketplace.MakeStorageAvailable(new CodexPlugin.StorageAvailability(
totalSpace: (5 * FilesizeMb).MB(),
maxDuration: TimeSpan.FromSeconds(((double)config.Proofs.Period) * 5.0),
minPriceForTotalSpace: 1.TstWei(),
maxCollateral: 999999.Tst())
);
}
return hosts;
return TimeSpan.FromSeconds(((double)config.Proofs.Period) * 8.0);
}
}
}

View File

@ -5,6 +5,7 @@ using CodexTests;
using DistTestCore;
using GethPlugin;
using Nethereum.Hex.HexConvertors.Extensions;
using Utils;
namespace CodexReleaseTests.MarketTests
{
@ -27,12 +28,6 @@ namespace CodexReleaseTests.MarketTests
handles.Remove(lifecycle);
}
protected override void OnCodexSetup(ICodexSetup setup)
{
base.OnCodexSetup(setup);
setup.EnableMarketplace(GetGeth(), GetContracts(), m => m.WithInitial(10.Eth(), StartingBalanceTST.Tst()));
}
protected IGethNode GetGeth()
{
return handles[Get()].Geth;
@ -43,10 +38,49 @@ namespace CodexReleaseTests.MarketTests
return handles[Get()].Contracts;
}
protected abstract int NumberOfHosts { get; }
protected abstract int NumberOfClients { get; }
protected abstract ByteSize HostAvailabilitySize { get; }
protected abstract TimeSpan HostAvailabilityMaxDuration { get; }
public ICodexNodeGroup StartHosts()
{
var hosts = StartCodex(NumberOfHosts, s => s
.WithName("host")
.EnableMarketplace(GetGeth(), GetContracts(), m => m
.WithInitial(10.Eth(), StartingBalanceTST.Tst())
.AsStorageNode()
)
);
var config = GetContracts().Deployment.Config;
foreach (var host in hosts)
{
host.Marketplace.MakeStorageAvailable(new CodexPlugin.StorageAvailability(
totalSpace: HostAvailabilitySize,
maxDuration: HostAvailabilityMaxDuration,
minPriceForTotalSpace: 1.TstWei(),
maxCollateral: 999999.Tst())
);
}
return hosts;
}
public ICodexNodeGroup StartClients()
{
return StartCodex(NumberOfClients, s => s
.WithName("client")
.EnableMarketplace(GetGeth(), GetContracts(), m => m
.WithInitial(10.Eth(), StartingBalanceTST.Tst())
)
);
}
public SlotFill[] GetOnChainSlotFills(ICodexNodeGroup possibleHosts, string purchaseId)
{
return GetOnChainSlotFills(possibleHosts)
.Where(f => f.SlotFilledEvent.RequestId.ToHex(true) == purchaseId)
var fills = GetOnChainSlotFills(possibleHosts);
return fills.Where(f => f
.SlotFilledEvent.RequestId.ToHex(false).ToLowerInvariant() == purchaseId.ToLowerInvariant())
.ToArray();
}
@ -56,7 +90,7 @@ namespace CodexReleaseTests.MarketTests
var fills = events.GetSlotFilledEvents();
return fills.Select(f =>
{
var host = possibleHosts.Single(h => h.EthAddress == f.Host);
var host = possibleHosts.Single(h => h.EthAddress.Address == f.Host.Address);
return new SlotFill(f, host);
}).ToArray();