mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-02-25 15:33:11 +00:00
Fixes faulty customization of chain generated DTOs
This commit is contained in:
parent
60e2d03c62
commit
2ce2da4d46
@ -7,7 +7,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
private ChainEvents(
|
||||
BlockInterval blockInterval,
|
||||
Request[] requests,
|
||||
StorageRequestedEventDTO[] requests,
|
||||
RequestFulfilledEventDTO[] fulfilled,
|
||||
RequestCancelledEventDTO[] cancelled,
|
||||
RequestFailedEventDTO[] failed,
|
||||
@ -30,7 +30,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
}
|
||||
|
||||
public BlockInterval BlockInterval { get; }
|
||||
public Request[] Requests { get; }
|
||||
public StorageRequestedEventDTO[] Requests { get; }
|
||||
public RequestFulfilledEventDTO[] Fulfilled { get; }
|
||||
public RequestCancelledEventDTO[] Cancelled { get; }
|
||||
public RequestFailedEventDTO[] Failed { get; }
|
||||
@ -54,7 +54,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
return new ChainEvents(
|
||||
events.BlockInterval,
|
||||
events.GetStorageRequests(),
|
||||
events.GetStorageRequestedEvents(),
|
||||
events.GetRequestFulfilledEvents(),
|
||||
events.GetRequestCancelledEvents(),
|
||||
events.GetRequestFailedEvents(),
|
||||
|
||||
@ -116,25 +116,22 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
ApplyTimeImplicitEvents(blockNumber, eventsUtc);
|
||||
}
|
||||
|
||||
private void ApplyEvent(Request request)
|
||||
private void ApplyEvent(StorageRequestedEventDTO @event)
|
||||
{
|
||||
if (requests.Any(r => Equal(r.Request.RequestId, request.RequestId)))
|
||||
if (requests.Any(r => Equal(r.RequestId, @event.RequestId)))
|
||||
{
|
||||
var r = FindRequest(request);
|
||||
var r = FindRequest(@event);
|
||||
if (r == null) throw new Exception("ChainState is inconsistent. Received already-known requestId that's not known.");
|
||||
|
||||
if (request.Block.BlockNumber != r.Request.Block.BlockNumber) throw new Exception("Same request found in different blocks.");
|
||||
if (request.Client != r.Request.Client) throw new Exception("Same request belongs to different clients.");
|
||||
if (request.Content.Cid.ToHex() != r.Request.Content.Cid.ToHex()) throw new Exception("Same request has different CIDs.");
|
||||
|
||||
if (@event.Block.BlockNumber != @event.Block.BlockNumber) throw new Exception("Same request found in different blocks.");
|
||||
log.Log("Received the same request-creation event multiple times.");
|
||||
return;
|
||||
}
|
||||
|
||||
var newRequest = new ChainStateRequest(log, request, RequestState.New);
|
||||
var request = contracts.GetRequest(@event.RequestId);
|
||||
var newRequest = new ChainStateRequest(log, @event.RequestId, @event.Block, request, RequestState.New);
|
||||
requests.Add(newRequest);
|
||||
|
||||
handler.OnNewRequest(new RequestEvent(request.Block, newRequest));
|
||||
handler.OnNewRequest(new RequestEvent(@event.Block, newRequest));
|
||||
}
|
||||
|
||||
private void ApplyEvent(RequestFulfilledEventDTO @event)
|
||||
@ -209,22 +206,22 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
}
|
||||
}
|
||||
|
||||
private ChainStateRequest? FindRequest(IHasRequestId request)
|
||||
private ChainStateRequest? FindRequest(IHasBlockAndRequestId hasBoth)
|
||||
{
|
||||
var r = requests.SingleOrDefault(r => Equal(r.Request.RequestId, request.RequestId));
|
||||
var r = requests.SingleOrDefault(r => Equal(r.RequestId, hasBoth.RequestId));
|
||||
if (r != null) return r;
|
||||
|
||||
try
|
||||
{
|
||||
var req = contracts.GetRequest(request.RequestId);
|
||||
var state = contracts.GetRequestState(req);
|
||||
var newRequest = new ChainStateRequest(log, req, state);
|
||||
var req = contracts.GetRequest(hasBoth.RequestId);
|
||||
var state = contracts.GetRequestState(hasBoth.RequestId);
|
||||
var newRequest = new ChainStateRequest(log, hasBoth.RequestId, hasBoth.Block, req, state);
|
||||
requests.Add(newRequest);
|
||||
return newRequest;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = $"Failed to get request with id '{request.RequestId.ToHex()}' from chain: {ex}";
|
||||
var msg = $"Failed to get request with id '{hasBoth.RequestId.ToHex()}' from chain: {ex}";
|
||||
log.Error(msg);
|
||||
handler.OnError(msg);
|
||||
return null;
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using BlockchainUtils;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using Logging;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using Utils;
|
||||
|
||||
namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
public interface IChainStateRequest
|
||||
{
|
||||
byte[] RequestId { get; }
|
||||
public BlockTimeEntry Block { get; }
|
||||
Request Request { get; }
|
||||
RequestState State { get; }
|
||||
DateTime ExpiryUtc { get; }
|
||||
@ -18,21 +22,27 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
private readonly ILog log;
|
||||
|
||||
public ChainStateRequest(ILog log, Request request, RequestState state)
|
||||
public ChainStateRequest(ILog log, byte[] requestId, BlockTimeEntry block, Request request, RequestState state)
|
||||
{
|
||||
if (requestId == null || requestId.Length != 32) throw new ArgumentException(nameof(requestId));
|
||||
|
||||
this.log = log;
|
||||
RequestId = requestId;
|
||||
Block = block;
|
||||
Request = request;
|
||||
State = state;
|
||||
|
||||
ExpiryUtc = request.Block.Utc + TimeSpan.FromSeconds((double)request.Expiry);
|
||||
FinishedUtc = request.Block.Utc + TimeSpan.FromSeconds((double)request.Ask.Duration);
|
||||
ExpiryUtc = Block.Utc + TimeSpan.FromSeconds((double)request.Expiry);
|
||||
FinishedUtc = Block.Utc + TimeSpan.FromSeconds((double)request.Ask.Duration);
|
||||
|
||||
Log($"[{request.Block.BlockNumber}] Created as {State}.");
|
||||
Log($"[{Block.BlockNumber}] Created as {State}.");
|
||||
|
||||
Client = new EthAddress(request.Client);
|
||||
Hosts = new RequestHosts();
|
||||
}
|
||||
|
||||
public byte[] RequestId { get; }
|
||||
public BlockTimeEntry Block { get; }
|
||||
public Request Request { get; }
|
||||
public RequestState State { get; private set; }
|
||||
public DateTime ExpiryUtc { get; }
|
||||
@ -48,7 +58,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
|
||||
public void Log(string msg)
|
||||
{
|
||||
log.Log($"Request '{Request.Id}': {msg}");
|
||||
log.Log($"Request '{RequestId.ToHex()}': {msg}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -46,4 +46,48 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class DoNothingThrowingChainEventHandler : IChainStateChangeHandler
|
||||
{
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestCancelled(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFulfilled(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex, bool isRepair)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSlotReservationsFull(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnError(string msg)
|
||||
{
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
public void OnProofSubmitted(BlockTimeEntry block, string id)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Logging;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using Utils;
|
||||
|
||||
namespace CodexContractsPlugin.ChainMonitor
|
||||
@ -46,7 +47,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
for (ulong slotIndex = 0; slotIndex < request.Request.Ask.Slots; slotIndex++)
|
||||
{
|
||||
var state = contracts.GetProofState(request.Request, slotIndex, lastBlockInPeriod, periodNumber);
|
||||
var state = contracts.GetProofState(request.RequestId, slotIndex, lastBlockInPeriod, periodNumber);
|
||||
|
||||
total++;
|
||||
if (state.Required)
|
||||
@ -116,7 +117,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
var missed = "None";
|
||||
if (MissedProofs.Length > 0)
|
||||
{
|
||||
missed = string.Join("+", MissedProofs.Select(p => $"{p.FormatHost()} missed {p.Request.Request.Id} slot {p.SlotIndex}"));
|
||||
missed = string.Join("+", MissedProofs.Select(p => $"{p.FormatHost()} missed {p.Request.RequestId.ToHex()} slot {p.SlotIndex}"));
|
||||
}
|
||||
return $"Period:{PeriodNumber}=[Slots:{TotalNumSlots},ProofsRequired:{TotalProofsRequired},ProofsMissed:{missed}]";
|
||||
}
|
||||
|
||||
@ -24,12 +24,12 @@ namespace CodexContractsPlugin
|
||||
|
||||
ICodexContractsEvents GetEvents(TimeRange timeRange);
|
||||
ICodexContractsEvents GetEvents(BlockInterval blockInterval);
|
||||
EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex);
|
||||
RequestState GetRequestState(Request request);
|
||||
EthAddress? GetSlotHost(byte[] requestId, decimal slotIndex);
|
||||
RequestState GetRequestState(byte[] requestId);
|
||||
Request GetRequest(byte[] requestId);
|
||||
ulong GetPeriodNumber(DateTime utc);
|
||||
void WaitUntilNextPeriod();
|
||||
ProofState GetProofState(Request storageRequest, decimal slotIndex, ulong blockNumber, ulong period);
|
||||
ProofState GetProofState(byte[] requestId, decimal slotIndex, ulong blockNumber, ulong period);
|
||||
|
||||
ICodexContracts WithDifferentGeth(IGethNode node);
|
||||
}
|
||||
@ -111,9 +111,9 @@ namespace CodexContractsPlugin
|
||||
return new CodexContractsEvents(log, gethNode, Deployment, blockInterval);
|
||||
}
|
||||
|
||||
public EthAddress? GetSlotHost(Request storageRequest, decimal slotIndex)
|
||||
public EthAddress? GetSlotHost(byte[] requestId, decimal slotIndex)
|
||||
{
|
||||
var slotId = GetSlotId(storageRequest, slotIndex);
|
||||
var slotId = GetSlotId(requestId, slotIndex);
|
||||
var func = new GetHostFunction
|
||||
{
|
||||
SlotId = slotId
|
||||
@ -123,17 +123,22 @@ namespace CodexContractsPlugin
|
||||
return new EthAddress(address);
|
||||
}
|
||||
|
||||
public RequestState GetRequestState(Request request)
|
||||
public RequestState GetRequestState(byte[] requestId)
|
||||
{
|
||||
if (requestId == null) throw new ArgumentNullException(nameof(requestId));
|
||||
if (requestId.Length != 32) throw new InvalidDataException(nameof(requestId) + $"{nameof(requestId)} length should be 32 bytes, but was: {requestId.Length}" + requestId.Length);
|
||||
|
||||
var func = new RequestStateFunction
|
||||
{
|
||||
RequestId = request.RequestId
|
||||
RequestId = requestId
|
||||
};
|
||||
return gethNode.Call<RequestStateFunction, RequestState>(Deployment.MarketplaceAddress, func);
|
||||
}
|
||||
|
||||
public Request GetRequest(byte[] requestId)
|
||||
{
|
||||
if (requestId == null) throw new ArgumentNullException(nameof(requestId));
|
||||
if (requestId.Length != 32) throw new InvalidDataException(nameof(requestId) + $"{nameof(requestId)} length should be 32 bytes, but was: {requestId.Length}" + requestId.Length);
|
||||
var func = new GetRequestFunction
|
||||
{
|
||||
RequestId = requestId
|
||||
@ -160,9 +165,9 @@ namespace CodexContractsPlugin
|
||||
Thread.Sleep(TimeSpan.FromSeconds(secondsLeft + 1));
|
||||
}
|
||||
|
||||
public ProofState GetProofState(Request storageRequest, decimal slotIndex, ulong blockNumber, ulong period)
|
||||
public ProofState GetProofState(byte[] requestId, decimal slotIndex, ulong blockNumber, ulong period)
|
||||
{
|
||||
var slotId = GetSlotId(storageRequest, slotIndex);
|
||||
var slotId = GetSlotId(requestId, slotIndex);
|
||||
|
||||
var required = IsProofRequired(slotId, blockNumber);
|
||||
if (!required) return new ProofState(false, false);
|
||||
@ -176,11 +181,11 @@ namespace CodexContractsPlugin
|
||||
return new CodexContractsAccess(log, node, Deployment);
|
||||
}
|
||||
|
||||
private byte[] GetSlotId(Request request, decimal slotIndex)
|
||||
private byte[] GetSlotId(byte[] requestId, decimal slotIndex)
|
||||
{
|
||||
var encoder = new ABIEncode();
|
||||
var encoded = encoder.GetABIEncoded(
|
||||
new ABIValue("bytes32", request.RequestId),
|
||||
new ABIValue("bytes32", requestId),
|
||||
new ABIValue("uint256", slotIndex.ToBig())
|
||||
);
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ namespace CodexContractsPlugin
|
||||
public interface ICodexContractsEvents
|
||||
{
|
||||
BlockInterval BlockInterval { get; }
|
||||
Request[] GetStorageRequests();
|
||||
StorageRequestedEventDTO[] GetStorageRequestedEvents();
|
||||
RequestFulfilledEventDTO[] GetRequestFulfilledEvents();
|
||||
RequestCancelledEventDTO[] GetRequestCancelledEvents();
|
||||
RequestFailedEventDTO[] GetRequestFailedEvents();
|
||||
@ -38,18 +38,10 @@ namespace CodexContractsPlugin
|
||||
|
||||
public BlockInterval BlockInterval { get; }
|
||||
|
||||
public Request[] GetStorageRequests()
|
||||
public StorageRequestedEventDTO[] GetStorageRequestedEvents()
|
||||
{
|
||||
var events = gethNode.GetEvents<StorageRequestedEventDTO>(deployment.MarketplaceAddress, BlockInterval);
|
||||
var i = new ContractInteractions(log, gethNode);
|
||||
return events.Select(e =>
|
||||
{
|
||||
var requestEvent = i.GetRequest(deployment.MarketplaceAddress, e.Event.RequestId);
|
||||
var result = requestEvent.ReturnValue1;
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
result.RequestId = e.Event.RequestId;
|
||||
return result;
|
||||
}).ToArray();
|
||||
return events.Select(SetBlockOnEvent).ToArray();
|
||||
}
|
||||
|
||||
public RequestFulfilledEventDTO[] GetRequestFulfilledEvents()
|
||||
|
||||
@ -17,48 +17,45 @@ namespace CodexContractsPlugin.Marketplace
|
||||
byte[] RequestId { get; set; }
|
||||
}
|
||||
|
||||
public interface IHasBlockAndRequestId : IHasBlock, IHasRequestId
|
||||
{
|
||||
}
|
||||
|
||||
public interface IHasSlotIndex
|
||||
{
|
||||
ulong SlotIndex { get; set; }
|
||||
}
|
||||
|
||||
public partial class Request : RequestBase, IHasBlock, IHasRequestId
|
||||
public partial class Request
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
public byte[] RequestId { get; set; }
|
||||
|
||||
public EthAddress ClientAddress { get { return new EthAddress(Client); } }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return RequestId.ToHex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class RequestFulfilledEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class StorageRequestedEventDTO : IHasBlockAndRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestCancelledEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class RequestFulfilledEventDTO : IHasBlockAndRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestFailedEventDTO : IHasBlock, IHasRequestId
|
||||
public partial class RequestCancelledEventDTO : IHasBlockAndRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
public partial class RequestFailedEventDTO : IHasBlockAndRequestId
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO : IHasBlockAndRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
@ -70,13 +67,13 @@ namespace CodexContractsPlugin.Marketplace
|
||||
}
|
||||
}
|
||||
|
||||
public partial class SlotFreedEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
public partial class SlotFreedEventDTO : IHasBlockAndRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
public partial class SlotReservationsFullEventDTO : IHasBlockAndRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
@ -88,7 +85,7 @@ namespace CodexContractsPlugin.Marketplace
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class ReserveSlotFunction : IHasBlock, IHasRequestId, IHasSlotIndex
|
||||
public partial class ReserveSlotFunction : IHasBlockAndRequestId, IHasSlotIndex
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
using CodexContractsPlugin;
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using Logging;
|
||||
|
||||
namespace CodexReleaseTests.MarketTests
|
||||
{
|
||||
public class ChainMonitor
|
||||
{
|
||||
private readonly ChainState chainMonitor;
|
||||
private readonly TimeSpan interval;
|
||||
private CancellationTokenSource cts = new CancellationTokenSource();
|
||||
private Task worker = null!;
|
||||
|
||||
public ChainMonitor(ILog log, ICodexContracts contracts, DateTime startUtc, TimeSpan interval)
|
||||
{
|
||||
chainMonitor = new ChainState(log, contracts, new DoNothingChainEventHandler(), startUtc, true);
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
worker = Task.Run(Worker);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
cts.Cancel();
|
||||
worker.Wait();
|
||||
|
||||
worker = null!;
|
||||
cts = null!;
|
||||
}
|
||||
|
||||
public PeriodMonitorResult GetPeriodReports()
|
||||
{
|
||||
return chainMonitor.PeriodMonitor.GetAndClearReports();
|
||||
}
|
||||
|
||||
private void Worker()
|
||||
{
|
||||
while (!cts.IsCancellationRequested)
|
||||
{
|
||||
Thread.Sleep(interval);
|
||||
chainMonitor.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,7 +35,6 @@ namespace CodexReleaseTests.MarketTests
|
||||
|
||||
request.WaitForStorageContractStarted();
|
||||
AssertContractSlotsAreFilledByHosts(request, hosts);
|
||||
AssertContractIsOnChain(request);
|
||||
|
||||
hosts.Stop(waitTillStopped: true);
|
||||
|
||||
@ -43,12 +42,6 @@ namespace CodexReleaseTests.MarketTests
|
||||
|
||||
var config = GetContracts().Deployment.Config;
|
||||
request.WaitForContractFailed(config);
|
||||
|
||||
Thread.Sleep(GetPeriodDuration());
|
||||
AssertContractIsOnChain(request);
|
||||
|
||||
Thread.Sleep(GetPeriodDuration());
|
||||
AssertContractIsOnChain(request);
|
||||
}
|
||||
|
||||
private void WaitForSlotFreedEvents()
|
||||
|
||||
@ -41,21 +41,13 @@ namespace CodexReleaseTests.MarketTests
|
||||
|
||||
WaitForContractStarted(request);
|
||||
AssertContractSlotsAreFilledByHosts(request, hosts);
|
||||
AssertContractIsOnChain(request);
|
||||
|
||||
request.WaitForStorageContractFinished();
|
||||
AssertContractIsOnChain(request);
|
||||
|
||||
AssertClientHasPaidForContract(pricePerBytePerSecond, client, request, hosts);
|
||||
AssertHostsWerePaidForContract(pricePerBytePerSecond, request, hosts);
|
||||
AssertHostsCollateralsAreUnchanged(hosts);
|
||||
AssertHostAvailabilitiesAreEmpty(hosts);
|
||||
|
||||
Thread.Sleep(GetPeriodDuration());
|
||||
AssertContractIsOnChain(request);
|
||||
|
||||
Thread.Sleep(GetPeriodDuration());
|
||||
AssertContractIsOnChain(request);
|
||||
}
|
||||
|
||||
private IStoragePurchaseContract CreateStorageRequest(ICodexNode client)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
using NUnit.Framework;
|
||||
|
||||
[assembly: LevelOfParallelism(2)]
|
||||
[assembly: LevelOfParallelism(3)]
|
||||
namespace CodexReleaseTests
|
||||
{
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ namespace CodexReleaseTests.Utils
|
||||
|
||||
private void Worker(Action onFailure)
|
||||
{
|
||||
var state = new ChainState(log, contracts, new DoNothingChainEventHandler(), startUtc, doProofPeriodMonitoring: true);
|
||||
var state = new ChainState(log, contracts, new DoNothingThrowingChainEventHandler(), startUtc, doProofPeriodMonitoring: true);
|
||||
Thread.Sleep(updateInterval);
|
||||
|
||||
log.Log("Chain monitoring started");
|
||||
|
||||
@ -176,8 +176,7 @@ namespace CodexReleaseTests.Utils
|
||||
var result = new ChainMonitor(log, contracts, startUtc);
|
||||
result.Start(() =>
|
||||
{
|
||||
log.Error("Failure in chain monitor. No chain updates after this point.");
|
||||
//Assert.Fail("Failure in chain monitor.");
|
||||
Assert.Fail("Failure in chain monitor.");
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@ -363,7 +362,7 @@ namespace CodexReleaseTests.Utils
|
||||
return Time.Retry(() =>
|
||||
{
|
||||
var events = GetContracts().GetEvents(GetTestRunTimeRange());
|
||||
var submitEvent = events.GetStorageRequests().SingleOrDefault(e => e.RequestId.ToHex(false) == contract.PurchaseId);
|
||||
var submitEvent = events.GetStorageRequestedEvents().SingleOrDefault(e => e.RequestId.ToHex() == contract.PurchaseId);
|
||||
if (submitEvent == null)
|
||||
{
|
||||
// We're too early.
|
||||
@ -405,8 +404,8 @@ namespace CodexReleaseTests.Utils
|
||||
// Check the creation event.
|
||||
AssertOnChainEvents(events =>
|
||||
{
|
||||
var onChainRequests = events.GetStorageRequests();
|
||||
if (onChainRequests.Any(r => r.Id == contract.PurchaseId)) return;
|
||||
var onChainRequests = events.GetStorageRequestedEvents();
|
||||
if (onChainRequests.Any(r => r.RequestId.ToHex() == contract.PurchaseId)) return;
|
||||
throw new Exception($"OnChain request {contract.PurchaseId} not found...");
|
||||
}, nameof(AssertContractIsOnChain));
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ namespace ExperimentalTests.BasicTests
|
||||
//Thread.Sleep(GethContainerRecipe.BlockInterval * blocks);
|
||||
|
||||
AssertBalance(contracts, client, Is.LessThan(clientInitialBalance), "Buyer was not charged for storage.");
|
||||
Assert.That(contracts.GetRequestState(request), Is.EqualTo(RequestState.Finished));
|
||||
Assert.That(contracts.GetRequestState(request.RequestId), Is.EqualTo(RequestState.Finished));
|
||||
}
|
||||
|
||||
private TrackedFile CreateFile(ByteSize fileSize)
|
||||
@ -148,24 +148,25 @@ namespace ExperimentalTests.BasicTests
|
||||
}, purchase.Expiry + TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(5), "Checking SlotFilled events");
|
||||
}
|
||||
|
||||
private void AssertStorageRequest(Request request, StoragePurchaseRequest purchase, ICodexContracts contracts, ICodexNode buyer)
|
||||
private void AssertStorageRequest(StorageRequestedEventDTO 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(contracts.GetRequestState(request.RequestId), Is.EqualTo(RequestState.Started));
|
||||
var r = contracts.GetRequest(request.RequestId);
|
||||
Assert.That(r.ClientAddress, Is.EqualTo(buyer.EthAddress));
|
||||
Assert.That(request.Ask.Slots, Is.EqualTo(purchase.MinRequiredNumberOfNodes));
|
||||
}
|
||||
|
||||
private Request GetOnChainStorageRequest(ICodexContracts contracts, IGethNode geth)
|
||||
private StorageRequestedEventDTO GetOnChainStorageRequest(ICodexContracts contracts, IGethNode geth)
|
||||
{
|
||||
var events = contracts.GetEvents(GetTestRunTimeRange());
|
||||
var requests = events.GetStorageRequests();
|
||||
var requests = events.GetStorageRequestedEvents();
|
||||
Assert.That(requests.Length, Is.EqualTo(1));
|
||||
return requests.Single();
|
||||
}
|
||||
|
||||
private void AssertContractSlot(ICodexContracts contracts, Request request, int contractSlotIndex)
|
||||
private void AssertContractSlot(ICodexContracts contracts, StorageRequestedEventDTO request, int contractSlotIndex)
|
||||
{
|
||||
var slotHost = contracts.GetSlotHost(request, contractSlotIndex);
|
||||
var slotHost = contracts.GetSlotHost(request.RequestId, contractSlotIndex);
|
||||
Assert.That(slotHost?.Address, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using DiscordRewards;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using System.Globalization;
|
||||
using System.Numerics;
|
||||
using Utils;
|
||||
@ -237,14 +238,15 @@ namespace TestNetRewarder
|
||||
|
||||
private string FormatRequestId(IChainStateRequest request)
|
||||
{
|
||||
return FormatRequestId(request.Request.Id);
|
||||
return FormatRequestId(request.RequestId);
|
||||
}
|
||||
|
||||
private string FormatRequestId(string id)
|
||||
private string FormatRequestId(byte[] id)
|
||||
{
|
||||
var str = id.ToHex();
|
||||
return
|
||||
$"({emojiMaps.StringToEmojis(id, 3)})" +
|
||||
$"`{id}`";
|
||||
$"({emojiMaps.StringToEmojis(str, 3)})" +
|
||||
$"`{str}`";
|
||||
}
|
||||
|
||||
private string BytesToHexString(byte[] bytes)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Numerics;
|
||||
using BlockchainUtils;
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using Utils;
|
||||
|
||||
namespace TraceContract
|
||||
@ -96,7 +97,7 @@ namespace TraceContract
|
||||
|
||||
private bool IsMyRequest(RequestEvent requestEvent)
|
||||
{
|
||||
return requestId == requestEvent.Request.Request.Id.ToLowerInvariant();
|
||||
return requestId == requestEvent.Request.RequestId.ToHex().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ using CodexContractsPlugin.ChainMonitor;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using Logging;
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
using Nethereum.Model;
|
||||
using Utils;
|
||||
|
||||
namespace TraceContract
|
||||
@ -28,10 +29,12 @@ namespace TraceContract
|
||||
var request = GetRequest();
|
||||
if (request == null) throw new Exception("Failed to find the purchase in the last week of transactions.");
|
||||
|
||||
log.Log($"Request started at {request.Block.Utc}");
|
||||
var contractEnd = RunToContractEnd(request);
|
||||
var creationEvent = FindRequestCreationEvent();
|
||||
|
||||
var requestTimeline = new TimeRange(request.Block.Utc.AddMinutes(-1.0), contractEnd.AddMinutes(1.0));
|
||||
log.Log($"Request started at {creationEvent.Block.Utc}");
|
||||
var contractEnd = RunToContractEnd(creationEvent);
|
||||
|
||||
var requestTimeline = new TimeRange(creationEvent.Block.Utc.AddMinutes(-1.0), contractEnd.AddMinutes(1.0));
|
||||
log.Log($"Request timeline: {requestTimeline.From} -> {requestTimeline.To}");
|
||||
|
||||
// For this timeline, we log all the calls to reserve-slot.
|
||||
@ -52,7 +55,7 @@ namespace TraceContract
|
||||
return requestTimeline;
|
||||
}
|
||||
|
||||
private DateTime RunToContractEnd(Request request)
|
||||
private DateTime RunToContractEnd(StorageRequestedEventDTO request)
|
||||
{
|
||||
var utc = request.Block.Utc.AddMinutes(-1.0);
|
||||
var tracker = new ChainRequestTracker(output, input.PurchaseId);
|
||||
@ -78,35 +81,35 @@ namespace TraceContract
|
||||
return tracker.FinishUtc;
|
||||
}
|
||||
|
||||
private Request? GetRequest()
|
||||
{
|
||||
var request = FindRequest(LastHour());
|
||||
if (request == null) request = FindRequest(LastDay());
|
||||
if (request == null) request = FindRequest(LastWeek());
|
||||
return request;
|
||||
}
|
||||
|
||||
private Request? FindRequest(TimeRange timeRange)
|
||||
{
|
||||
var events = contracts.GetEvents(timeRange);
|
||||
var requests = events.GetStorageRequests();
|
||||
|
||||
foreach (var r in requests)
|
||||
{
|
||||
if (IsThisRequest(r.RequestId))
|
||||
{
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool IsThisRequest(byte[] requestId)
|
||||
{
|
||||
return requestId.ToHex().ToLowerInvariant() == input.PurchaseId.ToLowerInvariant();
|
||||
}
|
||||
|
||||
private Request? GetRequest()
|
||||
{
|
||||
return contracts.GetRequest(input.RequestId);
|
||||
}
|
||||
|
||||
public StorageRequestedEventDTO FindRequestCreationEvent()
|
||||
{
|
||||
var range = new TimeRange(DateTime.UtcNow - TimeSpan.FromHours(3.0), DateTime.UtcNow);
|
||||
var limit = DateTime.UtcNow - TimeSpan.FromDays(30);
|
||||
|
||||
while (range.From > limit)
|
||||
{
|
||||
var events = contracts.GetEvents(range);
|
||||
foreach (var r in events.GetStorageRequestedEvents())
|
||||
{
|
||||
if (r.RequestId.ToHex() == input.RequestId.ToHex()) return r;
|
||||
}
|
||||
|
||||
range = new TimeRange(range.From - TimeSpan.FromHours(3.0), range.From);
|
||||
}
|
||||
|
||||
throw new Exception("Unable to find storage request creation event on-chain after (limit) " + Time.FormatTimestamp(limit));
|
||||
}
|
||||
|
||||
private static TimeRange LastHour()
|
||||
{
|
||||
return new TimeRange(DateTime.UtcNow.AddHours(-1.0), DateTime.UtcNow);
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace TraceContract
|
||||
using Nethereum.Hex.HexConvertors.Extensions;
|
||||
|
||||
namespace TraceContract
|
||||
{
|
||||
public class Input
|
||||
{
|
||||
@ -17,5 +19,15 @@
|
||||
//"066df09a3a2e2587cfd577a0e96186c915b113d02b331b06e56f808494cff2b4";
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] RequestId
|
||||
{
|
||||
get
|
||||
{
|
||||
var r = PurchaseId.HexToByteArray();
|
||||
if (r == null || r.Length != 32) throw new ArgumentException(nameof(PurchaseId));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,8 +50,7 @@ namespace TraceContract
|
||||
|
||||
public void LogRequestCreated(RequestEvent requestEvent)
|
||||
{
|
||||
var r = requestEvent.Request.Request;
|
||||
var msg = $"Storage request created: '{r.Id}' = {Environment.NewLine}${JsonConvert.SerializeObject(r, Formatting.Indented)}{Environment.NewLine}";
|
||||
var msg = $"Storage request created: '{requestEvent.Request.RequestId}' = {Environment.NewLine}${JsonConvert.SerializeObject(requestEvent.Request.Request, Formatting.Indented)}{Environment.NewLine}";
|
||||
Add(requestEvent.Block, msg);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user