contract successful test passed
This commit is contained in:
parent
d032b77abe
commit
4990bb2282
|
@ -25,7 +25,7 @@ namespace CodexContractsPlugin
|
|||
ICodexContractsEvents GetEvents(BlockInterval blockInterval);
|
||||
EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex);
|
||||
RequestState GetRequestState(Request request);
|
||||
void WithdrawFunds(string purchaseId, EthAddress address);
|
||||
void WaitUntilNextPeriod();
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
|
@ -116,24 +116,13 @@ namespace CodexContractsPlugin
|
|||
return gethNode.Call<RequestStateFunction, RequestState>(Deployment.MarketplaceAddress, func);
|
||||
}
|
||||
|
||||
public void WithdrawFunds(string purchaseId, EthAddress address)
|
||||
public void WaitUntilNextPeriod()
|
||||
{
|
||||
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);
|
||||
}
|
||||
log.Log("Waiting until next proof period...");
|
||||
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
var periodSeconds = (int)Deployment.Config.Proofs.Period;
|
||||
var secondsLeft = now % periodSeconds;
|
||||
Thread.Sleep(TimeSpan.FromSeconds(secondsLeft + 1));
|
||||
}
|
||||
|
||||
private ContractInteractions StartInteraction()
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace CodexPlugin
|
|||
|
||||
public void Announce()
|
||||
{
|
||||
tools.GetLog().Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}' - Revision: {codexStarter.GetCodexRevision()}");
|
||||
Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}' - Revision: {codexStarter.GetCodexRevision()}");
|
||||
}
|
||||
|
||||
public void AddMetadata(IAddMetadata metadata)
|
||||
|
@ -55,6 +55,10 @@ namespace CodexPlugin
|
|||
{
|
||||
mconfig.GethNode.SendEth(node, mconfig.MarketplaceSetup.InitialEth);
|
||||
mconfig.CodexContracts.MintTestTokens(node, mconfig.MarketplaceSetup.InitialTestTokens);
|
||||
|
||||
Log($"Send {mconfig.MarketplaceSetup.InitialEth} and " +
|
||||
$"minted {mconfig.MarketplaceSetup.InitialTestTokens} for " +
|
||||
$"{node.GetName()} (address: {node.EthAddress})");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,5 +74,10 @@ namespace CodexPlugin
|
|||
setup(codexSetup);
|
||||
return codexSetup;
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
{
|
||||
tools.GetLog().Log(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using CodexPlugin.Hooks;
|
||||
using CodexContractsPlugin;
|
||||
using CodexPlugin.Hooks;
|
||||
using GethPlugin;
|
||||
using Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Utils;
|
||||
|
@ -12,7 +14,7 @@ namespace CodexPlugin
|
|||
ContentId ContentId { get; }
|
||||
void WaitForStorageContractSubmitted();
|
||||
void WaitForStorageContractStarted();
|
||||
void WaitForStorageContractFinished();
|
||||
void WaitForStorageContractFinished(ICodexContracts contracts);
|
||||
}
|
||||
|
||||
public class StoragePurchaseContract : IStoragePurchaseContract
|
||||
|
@ -62,7 +64,7 @@ namespace CodexPlugin
|
|||
AssertDuration(SubmittedToStarted, timeout, nameof(SubmittedToStarted));
|
||||
}
|
||||
|
||||
public void WaitForStorageContractFinished()
|
||||
public void WaitForStorageContractFinished(ICodexContracts contracts)
|
||||
{
|
||||
if (!contractStartedUtc.HasValue)
|
||||
{
|
||||
|
@ -74,6 +76,12 @@ namespace CodexPlugin
|
|||
contractFinishedUtc = DateTime.UtcNow;
|
||||
LogFinishedDuration();
|
||||
AssertDuration(SubmittedToFinished, timeout, nameof(SubmittedToFinished));
|
||||
|
||||
contracts.WaitUntilNextPeriod();
|
||||
|
||||
var blocks = 3;
|
||||
Log($"Waiting {blocks} blocks for nodes to process payouts...");
|
||||
Thread.Sleep(GethContainerRecipe.BlockInterval * blocks);
|
||||
}
|
||||
|
||||
public StoragePurchase GetPurchaseStatus(string purchaseId)
|
||||
|
|
|
@ -6,6 +6,7 @@ namespace GethPlugin
|
|||
public class GethContainerRecipe : ContainerRecipeFactory
|
||||
{
|
||||
public static string DockerImage { get; } = "codexstorage/dist-tests-geth:latest";
|
||||
public static TimeSpan BlockInterval { get; } = TimeSpan.FromSeconds(1.0);
|
||||
private const string defaultArgs = "--ipcdisable --syncmode full";
|
||||
|
||||
public const string HttpPortTag = "http_port";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using CodexContractsPlugin;
|
||||
using CodexPlugin;
|
||||
using GethPlugin;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using NUnit.Framework;
|
||||
using Utils;
|
||||
|
||||
|
@ -15,7 +16,7 @@ namespace CodexReleaseTests.MarketTests
|
|||
protected override int NumberOfHosts => 4;
|
||||
protected override int NumberOfClients => 1;
|
||||
protected override ByteSize HostAvailabilitySize => (5 * FilesizeMb).MB();
|
||||
protected override TimeSpan HostAvailabilityMaxDuration => GetHostAvailabilityDuration();
|
||||
protected override TimeSpan HostAvailabilityMaxDuration => Get8TimesConfiguredPeriodDuration();
|
||||
|
||||
[Test]
|
||||
public void ContractSuccessful()
|
||||
|
@ -29,26 +30,15 @@ namespace CodexReleaseTests.MarketTests
|
|||
AssertContractIsOnChain(request);
|
||||
|
||||
request.WaitForStorageContractStarted();
|
||||
var slotFills = AssertContractSlotsAreFilledByHosts(request, hosts);
|
||||
AssertContractSlotsAreFilledByHosts(request, hosts);
|
||||
|
||||
request.WaitForStorageContractFinished();
|
||||
//EveryoneWithdrawsFunds(hosts, client);
|
||||
request.WaitForStorageContractFinished(GetContracts());
|
||||
|
||||
GetContracts().WithdrawFunds(request.PurchaseId, client.EthAddress);
|
||||
foreach (var host in hosts)
|
||||
GetContracts().WithdrawFunds(request.PurchaseId, host.EthAddress);
|
||||
|
||||
AssertClientHasPaidForContract(client, request);
|
||||
AssertHostsWerePaidForContract(request, hosts, slotFills);
|
||||
AssertClientHasPaidForContract(client, request, hosts);
|
||||
AssertHostsWerePaidForContract(request, hosts);
|
||||
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 =>
|
||||
|
@ -59,7 +49,7 @@ namespace CodexReleaseTests.MarketTests
|
|||
}, nameof(AssertContractIsOnChain));
|
||||
}
|
||||
|
||||
private SlotFill[] AssertContractSlotsAreFilledByHosts(IStoragePurchaseContract contract, ICodexNodeGroup hosts)
|
||||
private void AssertContractSlotsAreFilledByHosts(IStoragePurchaseContract contract, ICodexNodeGroup hosts)
|
||||
{
|
||||
var activeHosts = new Dictionary<int, SlotFill>();
|
||||
|
||||
|
@ -78,30 +68,32 @@ namespace CodexReleaseTests.MarketTests
|
|||
if (activeHosts.Count != contract.Purchase.MinRequiredNumberOfNodes) throw new Exception("Not all slots were filled...");
|
||||
|
||||
}, nameof(AssertContractSlotsAreFilledByHosts));
|
||||
|
||||
return activeHosts.Values.ToArray();
|
||||
}
|
||||
|
||||
private void AssertClientHasPaidForContract(ICodexNode client, IStoragePurchaseContract contract)
|
||||
private void AssertClientHasPaidForContract(ICodexNode client, IStoragePurchaseContract contract, ICodexNodeGroup hosts)
|
||||
{
|
||||
var balance = GetContracts().GetTestTokenBalance(client);
|
||||
var expectedBalance = StartingBalanceTST.Tst() - GetContractTotalCost();
|
||||
var balance = GetTstBalance(client);
|
||||
var expectedBalance = StartingBalanceTST.Tst() - GetContractFinalCost(contract, hosts);
|
||||
|
||||
Assert.That(balance, Is.EqualTo(expectedBalance), "Client balance incorrect.");
|
||||
}
|
||||
|
||||
private void AssertHostsWerePaidForContract(IStoragePurchaseContract contract, ICodexNodeGroup hosts, SlotFill[] fills)
|
||||
private void AssertHostsWerePaidForContract(IStoragePurchaseContract contract, ICodexNodeGroup hosts)
|
||||
{
|
||||
var fills = GetOnChainSlotFills(hosts);
|
||||
var submitUtc = GetContractOnChainSubmittedUtc(contract);
|
||||
var finishUtc = submitUtc + contract.Purchase.Duration;
|
||||
var expectedBalances = new Dictionary<EthAddress, TestToken>();
|
||||
foreach (var host in hosts) expectedBalances.Add(host.EthAddress, StartingBalanceTST.Tst());
|
||||
foreach (var fill in fills)
|
||||
{
|
||||
expectedBalances[fill.Host.EthAddress] += GetContractCostPerSlot();
|
||||
var slotDuration = finishUtc - fill.SlotFilledEvent.Block.Utc;
|
||||
expectedBalances[fill.Host.EthAddress] += GetContractCostPerSlot(slotDuration);
|
||||
}
|
||||
|
||||
foreach (var pair in expectedBalances)
|
||||
{
|
||||
var balance = GetContracts().GetTestTokenBalance(pair.Key);
|
||||
var balance = GetTstBalance(pair.Key);
|
||||
Assert.That(balance, Is.EqualTo(pair.Value), "Host was not paid for storage.");
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +104,7 @@ namespace CodexReleaseTests.MarketTests
|
|||
// All host balances should be equal to or greater than the starting balance.
|
||||
foreach (var host in hosts)
|
||||
{
|
||||
Assert.That(GetContracts().GetTestTokenBalance(host), Is.GreaterThanOrEqualTo(StartingBalanceTST.Tst()));
|
||||
Assert.That(GetTstBalance(host), Is.GreaterThanOrEqualTo(StartingBalanceTST.Tst()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,15 +133,32 @@ namespace CodexReleaseTests.MarketTests
|
|||
});
|
||||
}
|
||||
|
||||
private TestToken GetContractTotalCost()
|
||||
private TestToken GetContractFinalCost(IStoragePurchaseContract contract, ICodexNodeGroup hosts)
|
||||
{
|
||||
return GetContractCostPerSlot() * NumberOfHosts;
|
||||
var fills = GetOnChainSlotFills(hosts);
|
||||
var result = 0.Tst();
|
||||
var submitUtc = GetContractOnChainSubmittedUtc(contract);
|
||||
var finishUtc = submitUtc + contract.Purchase.Duration;
|
||||
|
||||
foreach (var fill in fills)
|
||||
{
|
||||
var slotDuration = finishUtc - fill.SlotFilledEvent.Block.Utc;
|
||||
result += GetContractCostPerSlot(slotDuration);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private TestToken GetContractCostPerSlot()
|
||||
private DateTime GetContractOnChainSubmittedUtc(IStoragePurchaseContract contract)
|
||||
{
|
||||
var duration = GetContractDuration();
|
||||
return PricePerSlotPerSecondTSTWei.TstWei() * ((int)duration.TotalSeconds);
|
||||
var events = GetContracts().GetEvents(GetTestRunTimeRange());
|
||||
var submitEvent = events.GetStorageRequests().Single(e => e.RequestId.ToHex(false) == contract.PurchaseId);
|
||||
return submitEvent.Block.Utc;
|
||||
}
|
||||
|
||||
private TestToken GetContractCostPerSlot(TimeSpan slotDuration)
|
||||
{
|
||||
return PricePerSlotPerSecondTSTWei.TstWei() * (int)slotDuration.TotalSeconds;
|
||||
}
|
||||
|
||||
private TimeSpan GetContractExpiry()
|
||||
|
@ -159,10 +168,10 @@ namespace CodexReleaseTests.MarketTests
|
|||
|
||||
private TimeSpan GetContractDuration()
|
||||
{
|
||||
return GetHostAvailabilityDuration() / 2;
|
||||
return Get8TimesConfiguredPeriodDuration() / 2;
|
||||
}
|
||||
|
||||
private TimeSpan GetHostAvailabilityDuration()
|
||||
private TimeSpan Get8TimesConfiguredPeriodDuration()
|
||||
{
|
||||
var config = GetContracts().Deployment.Config;
|
||||
return TimeSpan.FromSeconds(((double)config.Proofs.Period) * 8.0);
|
||||
|
|
|
@ -5,6 +5,7 @@ using CodexTests;
|
|||
using DistTestCore;
|
||||
using GethPlugin;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using NUnit.Framework;
|
||||
using Utils;
|
||||
|
||||
namespace CodexReleaseTests.MarketTests
|
||||
|
@ -13,6 +14,7 @@ namespace CodexReleaseTests.MarketTests
|
|||
{
|
||||
private readonly Dictionary<TestLifecycle, MarketplaceHandle> handles = new Dictionary<TestLifecycle, MarketplaceHandle>();
|
||||
protected const int StartingBalanceTST = 1000;
|
||||
protected const int StartingBalanceEth = 10;
|
||||
|
||||
protected override void LifecycleStart(TestLifecycle lifecycle)
|
||||
{
|
||||
|
@ -48,7 +50,7 @@ namespace CodexReleaseTests.MarketTests
|
|||
var hosts = StartCodex(NumberOfHosts, s => s
|
||||
.WithName("host")
|
||||
.EnableMarketplace(GetGeth(), GetContracts(), m => m
|
||||
.WithInitial(10.Eth(), StartingBalanceTST.Tst())
|
||||
.WithInitial(StartingBalanceEth.Eth(), StartingBalanceTST.Tst())
|
||||
.AsStorageNode()
|
||||
)
|
||||
);
|
||||
|
@ -56,6 +58,9 @@ namespace CodexReleaseTests.MarketTests
|
|||
var config = GetContracts().Deployment.Config;
|
||||
foreach (var host in hosts)
|
||||
{
|
||||
Assert.That(GetTstBalance(host).TstWei, Is.EqualTo(StartingBalanceTST.Tst().TstWei));
|
||||
Assert.That(GetEthBalance(host).Wei, Is.EqualTo(StartingBalanceEth.Eth().Wei));
|
||||
|
||||
host.Marketplace.MakeStorageAvailable(new CodexPlugin.StorageAvailability(
|
||||
totalSpace: HostAvailabilitySize,
|
||||
maxDuration: HostAvailabilityMaxDuration,
|
||||
|
@ -66,12 +71,32 @@ namespace CodexReleaseTests.MarketTests
|
|||
return hosts;
|
||||
}
|
||||
|
||||
public TestToken GetTstBalance(ICodexNode node)
|
||||
{
|
||||
return GetContracts().GetTestTokenBalance(node);
|
||||
}
|
||||
|
||||
public TestToken GetTstBalance(EthAddress address)
|
||||
{
|
||||
return GetContracts().GetTestTokenBalance(address);
|
||||
}
|
||||
|
||||
public Ether GetEthBalance(ICodexNode node)
|
||||
{
|
||||
return GetGeth().GetEthBalance(node);
|
||||
}
|
||||
|
||||
public Ether GetEthBalance(EthAddress address)
|
||||
{
|
||||
return GetGeth().GetEthBalance(address);
|
||||
}
|
||||
|
||||
public ICodexNodeGroup StartClients()
|
||||
{
|
||||
return StartCodex(NumberOfClients, s => s
|
||||
.WithName("client")
|
||||
.EnableMarketplace(GetGeth(), GetContracts(), m => m
|
||||
.WithInitial(10.Eth(), StartingBalanceTST.Tst())
|
||||
.WithInitial(StartingBalanceEth.Eth(), StartingBalanceTST.Tst())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace CodexTests.BasicTests
|
|||
AssertStorageRequest(request, purchase, contracts, client);
|
||||
AssertContractSlot(contracts, request, 0);
|
||||
|
||||
purchaseContract.WaitForStorageContractFinished();
|
||||
purchaseContract.WaitForStorageContractFinished(contracts);
|
||||
|
||||
AssertBalance(contracts, client, Is.LessThan(clientInitialBalance), "Buyer was not charged for storage.");
|
||||
Assert.That(contracts.GetRequestState(request), Is.EqualTo(RequestState.Finished));
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace CodexTests.UtilityTests
|
|||
|
||||
var purchaseContract = ClientPurchasesStorage(client);
|
||||
purchaseContract.WaitForStorageContractStarted();
|
||||
purchaseContract.WaitForStorageContractFinished();
|
||||
purchaseContract.WaitForStorageContractFinished(contracts);
|
||||
Thread.Sleep(rewarderInterval * 3);
|
||||
|
||||
apiCalls.Stop();
|
||||
|
|
Loading…
Reference in New Issue