Merge branch 'master' into feature/bot-upgrade
This commit is contained in:
commit
d3390892af
@ -16,7 +16,7 @@
|
||||
public class MarketAverage
|
||||
{
|
||||
public int NumberOfFinished { get; set; }
|
||||
public TimeSpan TimeRange { get; set; }
|
||||
public int TimeRangeSeconds { get; set; }
|
||||
public float Price { get; set; }
|
||||
public float Size { get; set; }
|
||||
public float Duration { get; set; }
|
||||
|
@ -18,6 +18,13 @@ namespace NethereumWorkflow.BlockUtils
|
||||
bounds = new BlockchainBounds(cache, web3);
|
||||
}
|
||||
|
||||
public BlockTimeEntry Get(ulong blockNumber)
|
||||
{
|
||||
var b = cache.Get(blockNumber);
|
||||
if (b != null) return b;
|
||||
return GetBlock(blockNumber);
|
||||
}
|
||||
|
||||
public ulong? GetHighestBlockNumberBefore(DateTime moment)
|
||||
{
|
||||
bounds.Initialize();
|
||||
|
@ -121,5 +121,12 @@ namespace NethereumWorkflow
|
||||
to: toBlock.Value
|
||||
);
|
||||
}
|
||||
|
||||
public BlockTimeEntry GetBlockForNumber(ulong number)
|
||||
{
|
||||
var wrapper = new Web3Wrapper(web3, log);
|
||||
var blockTimeFinder = new BlockTimeFinder(blockCache, wrapper, log);
|
||||
return blockTimeFinder.Get(number);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using Nethereum.ABI;
|
||||
using Nethereum.Hex.HexTypes;
|
||||
using Nethereum.Util;
|
||||
using NethereumWorkflow;
|
||||
using NethereumWorkflow.BlockUtils;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Utils;
|
||||
@ -89,7 +90,7 @@ namespace CodexContractsPlugin
|
||||
{
|
||||
var requestEvent = i.GetRequest(Deployment.MarketplaceAddress, e.Event.RequestId);
|
||||
var result = requestEvent.ReturnValue1;
|
||||
result.BlockNumber = e.Log.BlockNumber.ToUlong();
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
result.RequestId = e.Event.RequestId;
|
||||
return result;
|
||||
})
|
||||
@ -102,7 +103,7 @@ namespace CodexContractsPlugin
|
||||
return events.Select(e =>
|
||||
{
|
||||
var result = e.Event;
|
||||
result.BlockNumber = e.Log.BlockNumber.ToUlong();
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
return result;
|
||||
}).ToArray();
|
||||
}
|
||||
@ -113,7 +114,7 @@ namespace CodexContractsPlugin
|
||||
return events.Select(e =>
|
||||
{
|
||||
var result = e.Event;
|
||||
result.BlockNumber = e.Log.BlockNumber.ToUlong();
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
return result;
|
||||
}).ToArray();
|
||||
}
|
||||
@ -124,7 +125,7 @@ namespace CodexContractsPlugin
|
||||
return events.Select(e =>
|
||||
{
|
||||
var result = e.Event;
|
||||
result.BlockNumber = e.Log.BlockNumber.ToUlong();
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
result.Host = GetEthAddressFromTransaction(e.Log.TransactionHash);
|
||||
return result;
|
||||
}).ToArray();
|
||||
@ -136,7 +137,7 @@ namespace CodexContractsPlugin
|
||||
return events.Select(e =>
|
||||
{
|
||||
var result = e.Event;
|
||||
result.BlockNumber = e.Log.BlockNumber.ToUlong();
|
||||
result.Block = GetBlock(e.Log.BlockNumber.ToUlong());
|
||||
return result;
|
||||
}).ToArray();
|
||||
}
|
||||
@ -169,6 +170,11 @@ namespace CodexContractsPlugin
|
||||
return gethNode.Call<RequestStateFunction, RequestState>(Deployment.MarketplaceAddress, func);
|
||||
}
|
||||
|
||||
private BlockTimeEntry GetBlock(ulong number)
|
||||
{
|
||||
return gethNode.GetBlockForNumber(number);
|
||||
}
|
||||
|
||||
private EthAddress GetEthAddressFromTransaction(string transactionHash)
|
||||
{
|
||||
var transaction = gethNode.GetTransaction(transactionHash);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
using GethPlugin;
|
||||
using NethereumWorkflow.BlockUtils;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CodexContractsPlugin.Marketplace
|
||||
@ -7,7 +8,7 @@ namespace CodexContractsPlugin.Marketplace
|
||||
public partial class Request : RequestBase
|
||||
{
|
||||
[JsonIgnore]
|
||||
public ulong BlockNumber { get; set; }
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
public byte[] RequestId { get; set; }
|
||||
|
||||
public EthAddress ClientAddress { get { return new EthAddress(Client); } }
|
||||
@ -16,26 +17,26 @@ namespace CodexContractsPlugin.Marketplace
|
||||
public partial class RequestFulfilledEventDTO
|
||||
{
|
||||
[JsonIgnore]
|
||||
public ulong BlockNumber { get; set; }
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class RequestCancelledEventDTO
|
||||
{
|
||||
[JsonIgnore]
|
||||
public ulong BlockNumber { get; set; }
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFilledEventDTO
|
||||
{
|
||||
[JsonIgnore]
|
||||
public ulong BlockNumber { get; set; }
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
public EthAddress Host { get; set; }
|
||||
}
|
||||
|
||||
public partial class SlotFreedEventDTO
|
||||
{
|
||||
[JsonIgnore]
|
||||
public ulong BlockNumber { get; set; }
|
||||
public BlockTimeEntry Block { get; set; }
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
@ -5,6 +5,7 @@ using Nethereum.ABI.FunctionEncoding.Attributes;
|
||||
using Nethereum.Contracts;
|
||||
using Nethereum.RPC.Eth.DTOs;
|
||||
using NethereumWorkflow;
|
||||
using NethereumWorkflow.BlockUtils;
|
||||
using Utils;
|
||||
|
||||
namespace GethPlugin
|
||||
@ -27,6 +28,7 @@ namespace GethPlugin
|
||||
List<EventLog<TEvent>> GetEvents<TEvent>(string address, BlockInterval blockRange) where TEvent : IEventDTO, new();
|
||||
List<EventLog<TEvent>> GetEvents<TEvent>(string address, TimeRange timeRange) where TEvent : IEventDTO, new();
|
||||
BlockInterval ConvertTimeRangeToBlockRange(TimeRange timeRange);
|
||||
BlockTimeEntry GetBlockForNumber(ulong number);
|
||||
}
|
||||
|
||||
public class DeploymentGethNode : BaseGethNode, IGethNode
|
||||
@ -160,6 +162,11 @@ namespace GethPlugin
|
||||
return StartInteraction().ConvertTimeRangeToBlockRange(timeRange);
|
||||
}
|
||||
|
||||
public BlockTimeEntry GetBlockForNumber(ulong number)
|
||||
{
|
||||
return StartInteraction().GetBlockForNumber(number);
|
||||
}
|
||||
|
||||
protected abstract NethereumInteraction StartInteraction();
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ namespace BiblioTech.Commands
|
||||
|
||||
private string[] GetInsight(MarketAverage avg)
|
||||
{
|
||||
var headerLine = $"[Last {Time.FormatDuration(avg.TimeRange)}] ({avg.NumberOfFinished} Contracts finished)";
|
||||
var timeRange = TimeSpan.FromSeconds(avg.TimeRangeSeconds);
|
||||
var headerLine = $"[Last {Time.FormatDuration(timeRange)}] ({avg.NumberOfFinished} Contracts finished)";
|
||||
|
||||
if (avg.NumberOfFinished == 0)
|
||||
{
|
||||
|
@ -23,7 +23,10 @@ namespace BiblioTech.Rewards
|
||||
{
|
||||
try
|
||||
{
|
||||
Program.Averages = cmd.Averages;
|
||||
if (cmd.Averages != null && cmd.Averages.Any())
|
||||
{
|
||||
Program.Averages = cmd.Averages;
|
||||
}
|
||||
await Program.RoleDriver.GiveRewards(cmd);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -24,6 +24,16 @@ namespace BiblioTech.Rewards
|
||||
{
|
||||
Program.Log.Log($"Processing rewards command: '{JsonConvert.SerializeObject(rewards)}'");
|
||||
|
||||
if (rewards.Rewards.Any())
|
||||
{
|
||||
await ProcessRewards(rewards);
|
||||
}
|
||||
|
||||
await ProcessChainEvents(rewards.EventsOverview);
|
||||
}
|
||||
|
||||
private async Task ProcessRewards(GiveRewardsCommand rewards)
|
||||
{
|
||||
var guild = GetGuild();
|
||||
// We load all role and user information first,
|
||||
// so we don't ask the server for the same info multiple times.
|
||||
@ -33,7 +43,6 @@ namespace BiblioTech.Rewards
|
||||
rewardsChannel);
|
||||
|
||||
await context.ProcessGiveRewardsCommand(LookUpUsers(rewards));
|
||||
await ProcessChainEvents(rewards.EventsOverview);
|
||||
}
|
||||
|
||||
private SocketTextChannel? GetChannel(string name)
|
||||
|
@ -1,7 +1,5 @@
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using DiscordRewards;
|
||||
using DiscordRewards;
|
||||
using Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
|
||||
namespace TestNetRewarder
|
||||
@ -26,7 +24,7 @@ namespace TestNetRewarder
|
||||
|
||||
public async Task<bool> SendRewards(GiveRewardsCommand command)
|
||||
{
|
||||
if (command == null || command.Rewards == null || !command.Rewards.Any()) return false;
|
||||
if (command == null) return false;
|
||||
var result = await HttpPostJson(command);
|
||||
log.Log("Reward response: " + result);
|
||||
return result == "OK";
|
||||
|
@ -1,5 +1,6 @@
|
||||
using CodexContractsPlugin;
|
||||
using CodexContractsPlugin.Marketplace;
|
||||
using NethereumWorkflow.BlockUtils;
|
||||
using Newtonsoft.Json;
|
||||
using Utils;
|
||||
|
||||
@ -8,6 +9,29 @@ namespace TestNetRewarder
|
||||
public class ChainState
|
||||
{
|
||||
private readonly HistoricState historicState;
|
||||
private readonly string[] colorIcons = new[]
|
||||
{
|
||||
"🔴",
|
||||
"🟠",
|
||||
"🟡",
|
||||
"🟢",
|
||||
"🔵",
|
||||
"🟣",
|
||||
"🟤",
|
||||
"⚫",
|
||||
"⚪",
|
||||
"🟥",
|
||||
"🟧",
|
||||
"🟨",
|
||||
"🟩",
|
||||
"🟦",
|
||||
"🟪",
|
||||
"🟫",
|
||||
"⬛",
|
||||
"⬜",
|
||||
"🔶",
|
||||
"🔷"
|
||||
};
|
||||
|
||||
public ChainState(HistoricState historicState, ICodexContracts contracts, BlockInterval blockRange)
|
||||
{
|
||||
@ -44,6 +68,7 @@ namespace TestNetRewarder
|
||||
entries.AddRange(RequestCancelledEvents.Select(ToPair));
|
||||
entries.AddRange(SlotFilledEvents.Select(ToPair));
|
||||
entries.AddRange(SlotFreedEvents.Select(ToPair));
|
||||
entries.AddRange(FinishedRequests.Select(ToPair));
|
||||
|
||||
entries.Sort(new StringUtcComparer());
|
||||
|
||||
@ -52,46 +77,64 @@ namespace TestNetRewarder
|
||||
|
||||
private StringBlockNumberPair ToPair(Request r)
|
||||
{
|
||||
return new StringBlockNumberPair("NewRequest", JsonConvert.SerializeObject(r), r.BlockNumber);
|
||||
return new StringBlockNumberPair("NewRequest", JsonConvert.SerializeObject(r), r.Block, r.RequestId);
|
||||
}
|
||||
|
||||
public StringBlockNumberPair ToPair(StorageRequest r)
|
||||
{
|
||||
return new StringBlockNumberPair("FinishedRequest", JsonConvert.SerializeObject(r), r.Request.Block, r.Request.RequestId);
|
||||
}
|
||||
|
||||
private StringBlockNumberPair ToPair(RequestFulfilledEventDTO r)
|
||||
{
|
||||
return new StringBlockNumberPair("Fulfilled", JsonConvert.SerializeObject(r), r.BlockNumber);
|
||||
return new StringBlockNumberPair("Fulfilled", JsonConvert.SerializeObject(r), r.Block, r.RequestId);
|
||||
}
|
||||
|
||||
private StringBlockNumberPair ToPair(RequestCancelledEventDTO r)
|
||||
{
|
||||
return new StringBlockNumberPair("Cancelled", JsonConvert.SerializeObject(r), r.BlockNumber);
|
||||
return new StringBlockNumberPair("Cancelled", JsonConvert.SerializeObject(r), r.Block, r.RequestId);
|
||||
}
|
||||
|
||||
private StringBlockNumberPair ToPair(SlotFilledEventDTO r)
|
||||
{
|
||||
return new StringBlockNumberPair("SlotFilled", JsonConvert.SerializeObject(r), r.BlockNumber);
|
||||
return new StringBlockNumberPair("SlotFilled", JsonConvert.SerializeObject(r), r.Block, r.RequestId);
|
||||
}
|
||||
|
||||
private StringBlockNumberPair ToPair(SlotFreedEventDTO r)
|
||||
{
|
||||
return new StringBlockNumberPair("SlotFreed", JsonConvert.SerializeObject(r), r.BlockNumber);
|
||||
return new StringBlockNumberPair("SlotFreed", JsonConvert.SerializeObject(r), r.Block, r.RequestId);
|
||||
}
|
||||
|
||||
private string ToLine(StringBlockNumberPair pair)
|
||||
{
|
||||
return $"[{pair.Number}]({pair.Name}) {pair.Str}";
|
||||
var nl = Environment.NewLine;
|
||||
var colorIcon = GetColorIcon(pair.RequestId);
|
||||
return $"{colorIcon} {pair.Block} ({pair.Name}){nl}" +
|
||||
$"```json{nl}" +
|
||||
$"{pair.Str}{nl}" +
|
||||
$"```";
|
||||
}
|
||||
|
||||
private string GetColorIcon(byte[] requestId)
|
||||
{
|
||||
var index = requestId[0] % colorIcons.Length;
|
||||
return colorIcons[index];
|
||||
}
|
||||
|
||||
public class StringBlockNumberPair
|
||||
{
|
||||
public StringBlockNumberPair(string name, string str, ulong number)
|
||||
public StringBlockNumberPair(string name, string str, BlockTimeEntry block, byte[] requestId)
|
||||
{
|
||||
Name = name;
|
||||
Str = str;
|
||||
Number = number;
|
||||
Block = block;
|
||||
RequestId = requestId;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string Str { get; }
|
||||
public ulong Number { get; }
|
||||
public BlockTimeEntry Block { get; }
|
||||
public byte[] RequestId { get; }
|
||||
}
|
||||
|
||||
public class StringUtcComparer : IComparer<StringBlockNumberPair>
|
||||
@ -101,7 +144,7 @@ namespace TestNetRewarder
|
||||
if (x == null && y == null) return 0;
|
||||
if (x == null) return 1;
|
||||
if (y == null) return -1;
|
||||
return x.Number.CompareTo(y.Number);
|
||||
return x.Block.BlockNumber.CompareTo(y.Block.BlockNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ namespace TestNetRewarder
|
||||
private ChainState[] SelectStates(int numberOfIntervals)
|
||||
{
|
||||
if (numberOfIntervals < 1) return Array.Empty<ChainState>();
|
||||
if (numberOfIntervals > buffer.Count) return Array.Empty<ChainState>();
|
||||
return buffer.TakeLast(numberOfIntervals).ToArray();
|
||||
}
|
||||
|
||||
@ -52,7 +53,7 @@ namespace TestNetRewarder
|
||||
return new MarketAverage
|
||||
{
|
||||
NumberOfFinished = CountNumberOfFinishedRequests(states),
|
||||
TimeRange = GetTotalTimeRange(states),
|
||||
TimeRangeSeconds = GetTotalTimeRange(states),
|
||||
Price = Average(states, s => s.Request.Ask.Reward),
|
||||
Duration = Average(states, s => s.Request.Ask.Duration),
|
||||
Size = Average(states, s => GetTotalSize(s.Request.Ask)),
|
||||
@ -92,12 +93,13 @@ namespace TestNetRewarder
|
||||
}
|
||||
}
|
||||
|
||||
if (count < 1.0f) return 0.0f;
|
||||
return sum / count;
|
||||
}
|
||||
|
||||
private TimeSpan GetTotalTimeRange(ChainState[] states)
|
||||
private int GetTotalTimeRange(ChainState[] states)
|
||||
{
|
||||
return Program.Config.Interval * states.Length;
|
||||
return Convert.ToInt32((Program.Config.Interval * states.Length).TotalSeconds);
|
||||
}
|
||||
|
||||
private int CountNumberOfFinishedRequests(ChainState[] states)
|
||||
|
@ -67,9 +67,11 @@ namespace TestNetRewarder
|
||||
var marketAverages = GetMarketAverages(chainState);
|
||||
var eventsOverview = GenerateEventsOverview(chainState);
|
||||
|
||||
log.Log($"Found {outgoingRewards.Count} rewards to send. Found {marketAverages.Length} market averages.");
|
||||
log.Log($"Found {outgoingRewards.Count} rewards. " +
|
||||
$"Found {marketAverages.Length} market averages. " +
|
||||
$"Found {eventsOverview.Length} events.");
|
||||
|
||||
if (outgoingRewards.Any())
|
||||
if (outgoingRewards.Any() || marketAverages.Any() || eventsOverview.Any())
|
||||
{
|
||||
if (!await SendRewardsCommand(outgoingRewards, marketAverages, eventsOverview))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user