2
0
mirror of synced 2025-02-21 12:38:20 +00:00

Merge branch 'master' into feature/bot-upgrade

This commit is contained in:
Ben 2024-04-22 14:03:51 +02:00
commit d3390892af
No known key found for this signature in database
GPG Key ID: 541B9D8C9F1426A1
13 changed files with 119 additions and 33 deletions

View File

@ -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; }

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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.

View File

@ -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();
}
}

View File

@ -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)
{

View File

@ -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)

View File

@ -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)

View File

@ -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";

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -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))
{