Set up contract-failed event.
This commit is contained in:
parent
44dfa39737
commit
87bda475df
21
Framework/Utils/RollingAverage.cs
Normal file
21
Framework/Utils/RollingAverage.cs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace Utils
|
||||
{
|
||||
public static class RollingAverage
|
||||
{
|
||||
/// <param name="currentAverage">Value of average before new value is added.</param>
|
||||
/// <param name="newNumberOfValues">Number of values in average after new value is added.</param>
|
||||
/// <param name="newValue">New value to be added.</param>
|
||||
/// <returns>New average value.</returns>
|
||||
/// <exception cref="Exception">newNumberOfValues must be 1 or greater.</exception>
|
||||
public static float GetNewAverage(float currentAverage, int newNumberOfValues, float newValue)
|
||||
{
|
||||
if (newNumberOfValues < 1) throw new Exception("Should be at least 1 value.");
|
||||
|
||||
float n = newNumberOfValues;
|
||||
var originalValue = currentAverage;
|
||||
var originalValueWeight = ((n - 1.0f) / n);
|
||||
var newValueWeight = (1.0f / n);
|
||||
return (originalValue * originalValueWeight) + (newValue * newValueWeight);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
Request[] requests,
|
||||
RequestFulfilledEventDTO[] fulfilled,
|
||||
RequestCancelledEventDTO[] cancelled,
|
||||
RequestFailedEventDTO[] failed,
|
||||
SlotFilledEventDTO[] slotFilled,
|
||||
SlotFreedEventDTO[] slotFreed
|
||||
)
|
||||
@ -18,6 +19,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
Requests = requests;
|
||||
Fulfilled = fulfilled;
|
||||
Cancelled = cancelled;
|
||||
Failed = failed;
|
||||
SlotFilled = slotFilled;
|
||||
SlotFreed = slotFreed;
|
||||
}
|
||||
@ -26,6 +28,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
public Request[] Requests { get; }
|
||||
public RequestFulfilledEventDTO[] Fulfilled { get; }
|
||||
public RequestCancelledEventDTO[] Cancelled { get; }
|
||||
public RequestFailedEventDTO[] Failed { get; }
|
||||
public SlotFilledEventDTO[] SlotFilled { get; }
|
||||
public SlotFreedEventDTO[] SlotFreed { get; }
|
||||
|
||||
@ -37,6 +40,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
all.AddRange(Requests);
|
||||
all.AddRange(Fulfilled);
|
||||
all.AddRange(Cancelled);
|
||||
all.AddRange(Failed);
|
||||
all.AddRange(SlotFilled);
|
||||
all.AddRange(SlotFreed);
|
||||
return all.ToArray();
|
||||
@ -60,6 +64,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
events.GetStorageRequests(),
|
||||
events.GetRequestFulfilledEvents(),
|
||||
events.GetRequestCancelledEvents(),
|
||||
events.GetRequestFailedEvents(),
|
||||
events.GetSlotFilledEvents(),
|
||||
events.GetSlotFreedEvents()
|
||||
);
|
||||
|
@ -13,6 +13,7 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
void OnRequestFinished(RequestEvent requestEvent);
|
||||
void OnRequestFulfilled(RequestEvent requestEvent);
|
||||
void OnRequestCancelled(RequestEvent requestEvent);
|
||||
void OnRequestFailed(RequestEvent requestEvent);
|
||||
void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex);
|
||||
void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex);
|
||||
}
|
||||
@ -41,15 +42,12 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
this.log = new LogPrefixer(log, "(ChainState) ");
|
||||
this.contracts = contracts;
|
||||
handler = changeHandler;
|
||||
StartUtc = startUtc;
|
||||
TotalSpan = new TimeRange(startUtc, startUtc);
|
||||
}
|
||||
|
||||
public TimeRange TotalSpan { get; private set; }
|
||||
public IChainStateRequest[] Requests => requests.ToArray();
|
||||
|
||||
public DateTime StartUtc { get; }
|
||||
|
||||
public void Update()
|
||||
{
|
||||
Update(DateTime.UtcNow);
|
||||
@ -124,6 +122,14 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
handler.OnRequestCancelled(new RequestEvent(@event.Block, r));
|
||||
}
|
||||
|
||||
private void ApplyEvent(RequestFailedEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
if (r == null) return;
|
||||
r.UpdateState(@event.Block.BlockNumber, RequestState.Failed);
|
||||
handler.OnRequestFailed(new RequestEvent(@event.Block, r));
|
||||
}
|
||||
|
||||
private void ApplyEvent(SlotFilledEventDTO @event)
|
||||
{
|
||||
var r = FindRequest(@event.RequestId);
|
||||
|
@ -0,0 +1,55 @@
|
||||
using GethPlugin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
public class ChainStateChangeHandlerMux : IChainStateChangeHandler
|
||||
{
|
||||
public ChainStateChangeHandlerMux(params IChainStateChangeHandler[] handlers)
|
||||
{
|
||||
Handlers = handlers.ToList();
|
||||
}
|
||||
|
||||
public List<IChainStateChangeHandler> Handlers { get; } = new List<IChainStateChangeHandler>();
|
||||
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnNewRequest(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestCancelled(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnRequestCancelled(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnRequestFailed(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnRequestFinished(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFulfilled(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnRequestFulfilled(requestEvent);
|
||||
}
|
||||
|
||||
public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnSlotFilled(requestEvent, host, slotIndex);
|
||||
}
|
||||
|
||||
public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
foreach (var handler in Handlers) handler.OnSlotFreed(requestEvent, slotIndex);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@ namespace CodexContractsPlugin.ChainMonitor
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace CodexContractsPlugin
|
||||
Request[] GetStorageRequests();
|
||||
RequestFulfilledEventDTO[] GetRequestFulfilledEvents();
|
||||
RequestCancelledEventDTO[] GetRequestCancelledEvents();
|
||||
RequestFailedEventDTO[] GetRequestFailedEvents();
|
||||
SlotFilledEventDTO[] GetSlotFilledEvents();
|
||||
SlotFreedEventDTO[] GetSlotFreedEvents();
|
||||
}
|
||||
@ -71,6 +72,17 @@ namespace CodexContractsPlugin
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public RequestFailedEventDTO[] GetRequestFailedEvents()
|
||||
{
|
||||
var events = gethNode.GetEvents<RequestFailedEventDTO>(deployment.MarketplaceAddress, BlockInterval);
|
||||
return events.Select(e =>
|
||||
{
|
||||
var result = e.Event;
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
return result;
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
public SlotFilledEventDTO[] GetSlotFilledEvents()
|
||||
{
|
||||
var events = gethNode.GetEvents<SlotFilledEventDTO>(deployment.MarketplaceAddress, BlockInterval);
|
||||
|
@ -40,6 +40,12 @@ namespace CodexContractsPlugin.Marketplace
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestFailedEventDTO : IHasBlock
|
||||
{
|
||||
[JsonIgnore]
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO : IHasBlock
|
||||
{
|
||||
[JsonIgnore]
|
||||
|
@ -21,5 +21,16 @@ namespace FrameworkTests.Utils
|
||||
TimeSpan.FromSeconds(28)
|
||||
));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Averaging()
|
||||
{
|
||||
var first = RollingAverage.GetNewAverage(0.0f, 1, 1.0f);
|
||||
Assert.That(first, Is.EqualTo(1.0f));
|
||||
|
||||
var fifth = RollingAverage.GetNewAverage(5.0f, 5, 0.0f);
|
||||
var expected = new[] { 5.0f, 5.0f, 5.0f, 5.0f, 0.0f }.Average();
|
||||
Assert.That(fifth, Is.EqualTo(expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
Tools/MarketInsights/AppState.cs
Normal file
13
Tools/MarketInsights/AppState.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace MarketInsights
|
||||
{
|
||||
public class AppState
|
||||
{
|
||||
public AppState(Configuration config)
|
||||
{
|
||||
Config = config;
|
||||
}
|
||||
|
||||
public MarketOverview MarketOverview { get; set; } = new ();
|
||||
public Configuration Config { get; }
|
||||
}
|
||||
}
|
71
Tools/MarketInsights/AverageHistory.cs
Normal file
71
Tools/MarketInsights/AverageHistory.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using GethPlugin;
|
||||
using System.Numerics;
|
||||
using Utils;
|
||||
|
||||
namespace MarketInsights
|
||||
{
|
||||
public class AverageHistory
|
||||
{
|
||||
public readonly List<MarketTimeSegment> contributions = new List<MarketTimeSegment>();
|
||||
|
||||
}
|
||||
|
||||
public class ContributionBuilder : IChainStateChangeHandler
|
||||
{
|
||||
private readonly MarketTimeSegment segment = new MarketTimeSegment();
|
||||
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestToAverage(segment.Submitted, requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestCancelled(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestToAverage(segment.Expired, requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestToAverage(segment.Failed, requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestToAverage(segment.Finished, requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFulfilled(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestToAverage(segment.Started, requestEvent);
|
||||
}
|
||||
|
||||
public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
}
|
||||
|
||||
private void AddRequestToAverage(ContractAverages average, RequestEvent requestEvent)
|
||||
{
|
||||
average.Number++;
|
||||
average.Price = GetNewAverage(average.Price, average.Number, requestEvent.Request.Request.Ask.Reward);
|
||||
average.Size = GetNewAverage(average.Size, average.Number, requestEvent.Request.Request.Ask.SlotSize);
|
||||
average.Duration = GetNewAverage(average.Duration, average.Number, requestEvent.Request.Request.Ask.Duration);
|
||||
average.Collateral = GetNewAverage(average.Collateral, average.Number, requestEvent.Request.Request.Ask.Collateral);
|
||||
average.ProofProbability = GetNewAverage(average.ProofProbability, average.Number, requestEvent.Request.Request.Ask.ProofProbability);
|
||||
}
|
||||
|
||||
private float GetNewAverage(float currentAverage, int newNumberOfValues, BigInteger newValue)
|
||||
{
|
||||
return GetNewAverage(currentAverage, newNumberOfValues, (float)newValue);
|
||||
}
|
||||
|
||||
private float GetNewAverage(float currentAverage, int newNumberOfValues, float newValue)
|
||||
{
|
||||
return RollingAverage.GetNewAverage(currentAverage, newNumberOfValues, newValue);
|
||||
}
|
||||
}
|
||||
}
|
37
Tools/MarketInsights/Configuration.cs
Normal file
37
Tools/MarketInsights/Configuration.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using ArgsUniform;
|
||||
|
||||
namespace MarketInsights
|
||||
{
|
||||
public class Configuration
|
||||
{
|
||||
[Uniform("interval-minutes", "im", "INTERVALMINUTES", true, "time in minutes between updates.")]
|
||||
public int UpdateIntervalMinutes { get; set; } = 10;
|
||||
|
||||
[Uniform("max-random-seconds", "mrs", "MAXRANDOMSECONDS", false, "maximum random number of seconds added to update delay.")]
|
||||
public int MaxRandomIntervalSeconds { get; set; } = 120;
|
||||
|
||||
[Uniform("check-history", "ch", "CHECKHISTORY", true, "Unix epoc timestamp of a moment in history on which processing begins. Should be 'launch of the testnet'.")]
|
||||
public int CheckHistoryTimestamp { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 6 = 1h
|
||||
/// 144 = 24h
|
||||
/// 2520 = 1 week
|
||||
/// 10080 = 4 weeks
|
||||
/// </summary>
|
||||
[Uniform("timesegments", "ts", "TIMESEGMENTS", false, "Semi-colon separated integers. Each represents a multiple of intervals, for which a market timesegment will be generated.")]
|
||||
public string TimeSegments { get; set; } = "6;144;2520;10080";
|
||||
|
||||
[Uniform("fullhistory", "fh", "FULLHISTORY", false, "When not zero, market timesegment for 'entire history' will be included.")]
|
||||
public int FullHistory { get; set; } = 1;
|
||||
|
||||
public DateTime HistoryStartUtc
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CheckHistoryTimestamp == 0) throw new Exception("'check-history' unix timestamp is required. Set it to the start/launch moment of the testnet.");
|
||||
return DateTimeOffset.FromUnixTimeSeconds(CheckHistoryTimestamp).UtcDateTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,13 +6,20 @@ namespace MarketInsights.Controllers
|
||||
[Route("[controller]")]
|
||||
public class MarketController : ControllerBase
|
||||
{
|
||||
private readonly AppState appState;
|
||||
|
||||
public MarketController(AppState appState)
|
||||
{
|
||||
this.appState = appState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the most recent market overview.
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public MarketOverview Get()
|
||||
{
|
||||
return new MarketOverview();
|
||||
return appState.MarketOverview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,4 +16,9 @@
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Framework\ArgsUniform\ArgsUniform.csproj" />
|
||||
<ProjectReference Include="..\..\ProjectPlugins\CodexContractsPlugin\CodexContractsPlugin.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -2,6 +2,11 @@
|
||||
{
|
||||
public class MarketOverview
|
||||
{
|
||||
/// <summary>
|
||||
/// Moment when overview was last updated.
|
||||
/// </summary>
|
||||
public DateTime LastUpdatedUtc { get; set; }
|
||||
|
||||
public MarketTimeSegment[] TimeSegments { get; set; } = Array.Empty<MarketTimeSegment>();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
using ArgsUniform;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Reflection;
|
||||
|
||||
@ -8,9 +8,15 @@ namespace MarketInsights
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var uniformArgs = new ArgsUniform<Configuration>(PrintHelp, args);
|
||||
var config = uniformArgs.Parse(true);
|
||||
|
||||
var appState = new AppState(config);
|
||||
var updater = new Updater(appState);
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddSingleton(appState);
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
@ -34,10 +40,15 @@ namespace MarketInsights
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
updater.Run();
|
||||
app.Run();
|
||||
}
|
||||
|
||||
private static void PrintHelp()
|
||||
{
|
||||
Console.WriteLine("WebAPI for generating market overview for Codex network. Comes with OpenAPI swagger endpoint.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
Tools/MarketInsights/Updater.cs
Normal file
35
Tools/MarketInsights/Updater.cs
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
namespace MarketInsights
|
||||
{
|
||||
public class Updater
|
||||
{
|
||||
private readonly AppState appState;
|
||||
private readonly Tracker[] trackers;
|
||||
|
||||
public Updater(AppState appState)
|
||||
{
|
||||
this.appState = appState;
|
||||
trackers = CreateTrackers();
|
||||
}
|
||||
|
||||
private Tracker[] CreateTrackers()
|
||||
{
|
||||
var tokens = appState.Config.TimeSegments.Split(";", StringSplitOptions.RemoveEmptyEntries);
|
||||
var nums = tokens.Select(t => Convert.ToInt32(t)).ToArray();
|
||||
return nums.Select(n => new Tracker(n)).ToArray();
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class Tracker
|
||||
{
|
||||
public Tracker(int numberOfSegments)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
using CodexContractsPlugin.ChainMonitor;
|
||||
using GethPlugin;
|
||||
using System.Numerics;
|
||||
|
||||
namespace TestNetRewarder
|
||||
{
|
||||
public class ChainChangeMux : IChainStateChangeHandler
|
||||
{
|
||||
private readonly IChainStateChangeHandler[] handlers;
|
||||
|
||||
public ChainChangeMux(params IChainStateChangeHandler[] handlers)
|
||||
{
|
||||
this.handlers = handlers;
|
||||
}
|
||||
|
||||
public void OnNewRequest(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnNewRequest(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestCancelled(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnRequestCancelled(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnRequestFinished(requestEvent);
|
||||
}
|
||||
|
||||
public void OnRequestFulfilled(RequestEvent requestEvent)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnRequestFulfilled(requestEvent);
|
||||
}
|
||||
|
||||
public void OnSlotFilled(RequestEvent requestEvent, EthAddress host, BigInteger slotIndex)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnSlotFilled(requestEvent, host, slotIndex);
|
||||
}
|
||||
|
||||
public void OnSlotFreed(RequestEvent requestEvent, BigInteger slotIndex)
|
||||
{
|
||||
foreach (var handler in handlers) handler.OnSlotFreed(requestEvent, slotIndex);
|
||||
}
|
||||
}
|
||||
}
|
@ -44,6 +44,11 @@ namespace TestNetRewarder
|
||||
AddRequestBlock(requestEvent, "Cancelled");
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestBlock(requestEvent, "Failed");
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
AddRequestBlock(requestEvent, "Finished");
|
||||
|
@ -70,5 +70,10 @@ namespace TestNetRewarder
|
||||
}
|
||||
return Array.Empty<int>();
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
throw new NotImplementedException("being removed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ namespace TestNetRewarder
|
||||
marketTracker = new MarketTracker(config, log);
|
||||
eventsFormatter = new EventsFormatter();
|
||||
|
||||
var handler = new ChainChangeMux(
|
||||
var handler = new ChainStateChangeHandlerMux(
|
||||
rewardChecker.Handler,
|
||||
marketTracker,
|
||||
eventsFormatter
|
||||
|
@ -34,6 +34,10 @@ namespace TestNetRewarder
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFailed(RequestEvent requestEvent)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnRequestFinished(RequestEvent requestEvent)
|
||||
{
|
||||
if (MeetsRequirements(CheckType.HostFinishedSlot, requestEvent))
|
||||
|
@ -9,7 +9,7 @@ namespace TestNetRewarder
|
||||
{
|
||||
var repo = new RewardRepo();
|
||||
var checks = repo.Rewards.Select(r => new RewardCheck(r, giver)).ToArray();
|
||||
Handler = new ChainChangeMux(checks);
|
||||
Handler = new ChainStateChangeHandlerMux(checks);
|
||||
}
|
||||
|
||||
public IChainStateChangeHandler Handler { get; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user