Debugging time segmenter
This commit is contained in:
parent
3c210f96fc
commit
da4101a042
@ -52,7 +52,13 @@ namespace NethereumWorkflow
|
|||||||
return closestBefore.BlockNumber;
|
return closestBefore.BlockNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
FetchBlocksAround(moment);
|
var newBlocks = FetchBlocksAround(moment);
|
||||||
|
if (newBlocks == 0)
|
||||||
|
{
|
||||||
|
log.Log("Didn't find any new blocks.");
|
||||||
|
if (closestBefore != null) return closestBefore.BlockNumber;
|
||||||
|
throw new Exception("Failed to find highest before.");
|
||||||
|
}
|
||||||
return GetHighestBlockBefore(moment);
|
return GetHighestBlockBefore(moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,11 +77,17 @@ namespace NethereumWorkflow
|
|||||||
return closestAfter.BlockNumber;
|
return closestAfter.BlockNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
FetchBlocksAround(moment);
|
var newBlocks = FetchBlocksAround(moment);
|
||||||
|
if (newBlocks == 0)
|
||||||
|
{
|
||||||
|
log.Log("Didn't find any new blocks.");
|
||||||
|
if (closestAfter != null) return closestAfter.BlockNumber;
|
||||||
|
throw new Exception("Failed to find lowest before.");
|
||||||
|
}
|
||||||
return GetLowestBlockAfter(moment);
|
return GetLowestBlockAfter(moment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchBlocksAround(DateTime moment)
|
private int FetchBlocksAround(DateTime moment)
|
||||||
{
|
{
|
||||||
var timePerBlock = EstimateTimePerBlock();
|
var timePerBlock = EstimateTimePerBlock();
|
||||||
log.Debug("Fetching blocks around " + moment.ToString("o") + " timePerBlock: " + timePerBlock.TotalSeconds);
|
log.Debug("Fetching blocks around " + moment.ToString("o") + " timePerBlock: " + timePerBlock.TotalSeconds);
|
||||||
@ -85,42 +97,55 @@ namespace NethereumWorkflow
|
|||||||
var max = entries.Keys.Max();
|
var max = entries.Keys.Max();
|
||||||
var blockDifference = CalculateBlockDifference(moment, timePerBlock, max);
|
var blockDifference = CalculateBlockDifference(moment, timePerBlock, max);
|
||||||
|
|
||||||
FetchUp(max, blockDifference);
|
return
|
||||||
FetchDown(max, blockDifference);
|
FetchUp(max, blockDifference) +
|
||||||
|
FetchDown(max, blockDifference);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchDown(ulong max, ulong blockDifference)
|
private int FetchDown(ulong max, ulong blockDifference)
|
||||||
{
|
{
|
||||||
var target = max - blockDifference - 1;
|
var target = GetTarget(max, blockDifference);
|
||||||
var fetchDown = FetchRange;
|
var fetchDown = FetchRange;
|
||||||
|
var newBlocks = 0;
|
||||||
while (fetchDown > 0)
|
while (fetchDown > 0)
|
||||||
{
|
{
|
||||||
if (!entries.ContainsKey(target))
|
if (!entries.ContainsKey(target))
|
||||||
{
|
{
|
||||||
var newBlock = AddBlockNumber(target);
|
var newBlock = AddBlockNumber("FD" + fetchDown, target);
|
||||||
if (newBlock == null) return;
|
if (newBlock == null) return newBlocks;
|
||||||
|
newBlocks++;
|
||||||
fetchDown--;
|
fetchDown--;
|
||||||
}
|
}
|
||||||
target--;
|
target--;
|
||||||
if (target <= 0) return;
|
if (target <= 0) return newBlocks;
|
||||||
}
|
}
|
||||||
|
return newBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchUp(ulong max, ulong blockDifference)
|
private int FetchUp(ulong max, ulong blockDifference)
|
||||||
{
|
{
|
||||||
var target = max - blockDifference;
|
var target = GetTarget(max, blockDifference);
|
||||||
var fetchUp = FetchRange;
|
var fetchUp = FetchRange;
|
||||||
|
var newBlocks = 0;
|
||||||
while (fetchUp > 0)
|
while (fetchUp > 0)
|
||||||
{
|
{
|
||||||
if (!entries.ContainsKey(target))
|
if (!entries.ContainsKey(target))
|
||||||
{
|
{
|
||||||
var newBlock = AddBlockNumber(target);
|
var newBlock = AddBlockNumber("FU" + fetchUp, target);
|
||||||
if (newBlock == null) return;
|
if (newBlock == null) return newBlocks;
|
||||||
|
newBlocks++;
|
||||||
fetchUp--;
|
fetchUp--;
|
||||||
}
|
}
|
||||||
target++;
|
target++;
|
||||||
if (target >= max) return;
|
if (target >= max) return newBlocks;
|
||||||
}
|
}
|
||||||
|
return newBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ulong GetTarget(ulong max, ulong blockDifference)
|
||||||
|
{
|
||||||
|
if (max <= blockDifference) return 1;
|
||||||
|
return max - blockDifference;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong CalculateBlockDifference(DateTime moment, TimeSpan timePerBlock, ulong max)
|
private ulong CalculateBlockDifference(DateTime moment, TimeSpan timePerBlock, ulong max)
|
||||||
@ -155,13 +180,14 @@ namespace NethereumWorkflow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockTimeEntry? AddBlockNumber(decimal blockNumber)
|
private BlockTimeEntry? AddBlockNumber(string a, decimal blockNumber)
|
||||||
{
|
{
|
||||||
return AddBlockNumber(Convert.ToUInt64(blockNumber));
|
return AddBlockNumber(a, Convert.ToUInt64(blockNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
private BlockTimeEntry? AddBlockNumber(ulong blockNumber)
|
private BlockTimeEntry? AddBlockNumber(string a, ulong blockNumber)
|
||||||
{
|
{
|
||||||
|
log.Log(a + " - Adding blockNumber: " + blockNumber);
|
||||||
if (entries.ContainsKey(blockNumber))
|
if (entries.ContainsKey(blockNumber))
|
||||||
{
|
{
|
||||||
return entries[blockNumber];
|
return entries[blockNumber];
|
||||||
@ -190,9 +216,10 @@ namespace NethereumWorkflow
|
|||||||
{
|
{
|
||||||
var min = entries.Keys.Min();
|
var min = entries.Keys.Min();
|
||||||
var max = entries.Keys.Max();
|
var max = entries.Keys.Max();
|
||||||
|
log.Log("min/max: " + min + " / " + max);
|
||||||
var clippedMin = Math.Max(max - 100, min);
|
var clippedMin = Math.Max(max - 100, min);
|
||||||
var minTime = entries[min].Utc;
|
var minTime = entries[min].Utc;
|
||||||
var clippedMinBlock = AddBlockNumber(clippedMin);
|
var clippedMinBlock = AddBlockNumber("EST", clippedMin);
|
||||||
if (clippedMinBlock != null) minTime = clippedMinBlock.Utc;
|
if (clippedMinBlock != null) minTime = clippedMinBlock.Utc;
|
||||||
|
|
||||||
var maxTime = entries[max].Utc;
|
var maxTime = entries[max].Utc;
|
||||||
@ -212,7 +239,7 @@ namespace NethereumWorkflow
|
|||||||
if (!entries.Any())
|
if (!entries.Any())
|
||||||
{
|
{
|
||||||
AddCurrentBlock();
|
AddCurrentBlock();
|
||||||
AddBlockNumber(entries.Single().Key - 1);
|
AddBlockNumber("INIT", entries.Single().Key - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +252,7 @@ namespace NethereumWorkflow
|
|||||||
{
|
{
|
||||||
var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync());
|
var number = Time.Wait(web3.Eth.Blocks.GetBlockNumber.SendRequestAsync());
|
||||||
var blockNumber = number.ToDecimal();
|
var blockNumber = number.ToDecimal();
|
||||||
return AddBlockNumber(blockNumber);
|
return AddBlockNumber("CUR", blockNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DateTime? GetTimestampFromBlock(ulong blockNumber)
|
private DateTime? GetTimestampFromBlock(ulong blockNumber)
|
||||||
@ -238,7 +265,7 @@ namespace NethereumWorkflow
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
int i = 0;
|
log.Error(nameof(GetTimestampFromBlock) + " Exception: " + ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ using Nethereum.ABI.FunctionEncoding.Attributes;
|
|||||||
using Nethereum.Contracts;
|
using Nethereum.Contracts;
|
||||||
using Nethereum.RPC.Eth.DTOs;
|
using Nethereum.RPC.Eth.DTOs;
|
||||||
using Nethereum.Web3;
|
using Nethereum.Web3;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
namespace NethereumWorkflow
|
namespace NethereumWorkflow
|
||||||
@ -90,14 +89,18 @@ namespace NethereumWorkflow
|
|||||||
{
|
{
|
||||||
var blockTimeFinder = new BlockTimeFinder(web3, log);
|
var blockTimeFinder = new BlockTimeFinder(web3, log);
|
||||||
|
|
||||||
var fromBlock = blockTimeFinder.GetLowestBlockNumberAfter(timeRange.From);
|
var lowest = blockTimeFinder.GetLowestBlockNumberAfter(timeRange.From);
|
||||||
var toBlock = blockTimeFinder.GetHighestBlockNumberBefore(timeRange.To);
|
var highest = blockTimeFinder.GetHighestBlockNumberBefore(timeRange.To);
|
||||||
|
|
||||||
|
var fromBlock = Math.Min(lowest, highest);
|
||||||
|
var toBlock = Math.Max(lowest, highest);
|
||||||
|
|
||||||
return GetEvents<TEvent>(address, fromBlock, toBlock);
|
return GetEvents<TEvent>(address, fromBlock, toBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EventLog<TEvent>> GetEvents<TEvent>(string address, ulong fromBlockNumber, ulong toBlockNumber) where TEvent : IEventDTO, new()
|
public List<EventLog<TEvent>> GetEvents<TEvent>(string address, ulong fromBlockNumber, ulong toBlockNumber) where TEvent : IEventDTO, new()
|
||||||
{
|
{
|
||||||
|
log.Debug($"Getting events of type [{typeof(TEvent).Name}] in block range [{fromBlockNumber} - {toBlockNumber}]");
|
||||||
var eventHandler = web3.Eth.GetEvent<TEvent>(address);
|
var eventHandler = web3.Eth.GetEvent<TEvent>(address);
|
||||||
var from = new BlockParameter(fromBlockNumber);
|
var from = new BlockParameter(fromBlockNumber);
|
||||||
var to = new BlockParameter(toBlockNumber);
|
var to = new BlockParameter(toBlockNumber);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
|
@ -26,12 +26,10 @@ namespace BiblioTech
|
|||||||
Program.AdminChecker.SetGuild(guild);
|
Program.AdminChecker.SetGuild(guild);
|
||||||
Program.Log.Log($"Initializing for guild: '{guild.Name}'");
|
Program.Log.Log($"Initializing for guild: '{guild.Name}'");
|
||||||
|
|
||||||
var roleController = new RoleController(client);
|
|
||||||
var rewardsApi = new RewardsApi(roleController);
|
|
||||||
|
|
||||||
var adminChannels = guild.TextChannels.Where(Program.AdminChecker.IsAdminChannel).ToArray();
|
var adminChannels = guild.TextChannels.Where(Program.AdminChecker.IsAdminChannel).ToArray();
|
||||||
if (adminChannels == null || !adminChannels.Any()) throw new Exception("No admin message channel");
|
if (adminChannels == null || !adminChannels.Any()) throw new Exception("No admin message channel");
|
||||||
Program.AdminChecker.SetAdminChannel(adminChannels.First());
|
Program.AdminChecker.SetAdminChannel(adminChannels.First());
|
||||||
|
Program.RoleDriver = new RoleDriver(client);
|
||||||
|
|
||||||
var builders = commands.Select(c =>
|
var builders = commands.Select(c =>
|
||||||
{
|
{
|
||||||
@ -62,8 +60,6 @@ namespace BiblioTech
|
|||||||
var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented);
|
var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented);
|
||||||
Program.Log.Error(json);
|
Program.Log.Error(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
rewardsApi.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SlashCommandHandler(SocketSlashCommand command)
|
private async Task SlashCommandHandler(SocketSlashCommand command)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using ArgsUniform;
|
using ArgsUniform;
|
||||||
using BiblioTech.Commands;
|
using BiblioTech.Commands;
|
||||||
|
using BiblioTech.Rewards;
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using Logging;
|
using Logging;
|
||||||
@ -13,6 +14,7 @@ namespace BiblioTech
|
|||||||
public static Configuration Config { get; private set; } = null!;
|
public static Configuration Config { get; private set; } = null!;
|
||||||
public static UserRepo UserRepo { get; } = new UserRepo();
|
public static UserRepo UserRepo { get; } = new UserRepo();
|
||||||
public static AdminChecker AdminChecker { get; private set; } = null!;
|
public static AdminChecker AdminChecker { get; private set; } = null!;
|
||||||
|
public static IDiscordRoleDriver RoleDriver { get; set; } = null!;
|
||||||
public static ILog Log { get; private set; } = null!;
|
public static ILog Log { get; private set; } = null!;
|
||||||
|
|
||||||
public static Task Main(string[] args)
|
public static Task Main(string[] args)
|
||||||
@ -29,10 +31,10 @@ namespace BiblioTech
|
|||||||
EnsurePath(Config.UserDataPath);
|
EnsurePath(Config.UserDataPath);
|
||||||
EnsurePath(Config.EndpointsPath);
|
EnsurePath(Config.EndpointsPath);
|
||||||
|
|
||||||
return new Program().MainAsync();
|
return new Program().MainAsync(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task MainAsync()
|
public async Task MainAsync(string[] args)
|
||||||
{
|
{
|
||||||
Log.Log("Starting Codex Discord Bot...");
|
Log.Log("Starting Codex Discord Bot...");
|
||||||
client = new DiscordSocketClient();
|
client = new DiscordSocketClient();
|
||||||
@ -52,10 +54,19 @@ namespace BiblioTech
|
|||||||
|
|
||||||
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
await client.LoginAsync(TokenType.Bot, Config.ApplicationToken);
|
||||||
await client.StartAsync();
|
await client.StartAsync();
|
||||||
|
|
||||||
AdminChecker = new AdminChecker();
|
AdminChecker = new AdminChecker();
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
builder.WebHost.ConfigureKestrel((context, options) =>
|
||||||
|
{
|
||||||
|
options.ListenAnyIP(Config.RewardApiPort);
|
||||||
|
});
|
||||||
|
builder.Services.AddControllers();
|
||||||
|
var app = builder.Build();
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
Log.Log("Running...");
|
Log.Log("Running...");
|
||||||
|
await app.RunAsync();
|
||||||
await Task.Delay(-1);
|
await Task.Delay(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
Tools/BiblioTech/Properties/launchSettings.json
Normal file
12
Tools/BiblioTech/Properties/launchSettings.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"BiblioTech": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"applicationUrl": "https://localhost:52960;http://localhost:52961"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
Tools/BiblioTech/Rewards/RewardController.cs
Normal file
35
Tools/BiblioTech/Rewards/RewardController.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using DiscordRewards;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace BiblioTech.Rewards
|
||||||
|
{
|
||||||
|
public interface IDiscordRoleDriver
|
||||||
|
{
|
||||||
|
Task GiveRewards(GiveRewardsCommand rewards);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public class RewardController : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpGet]
|
||||||
|
public string Ping()
|
||||||
|
{
|
||||||
|
return "Pong";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<string> Give(GiveRewardsCommand cmd)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Program.RoleDriver.GiveRewards(cmd);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Program.Log.Error("Exception: " + ex);
|
||||||
|
}
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,91 +0,0 @@
|
|||||||
using DiscordRewards;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Net;
|
|
||||||
using TaskFactory = Utils.TaskFactory;
|
|
||||||
|
|
||||||
namespace BiblioTech.Rewards
|
|
||||||
{
|
|
||||||
public interface IDiscordRoleController
|
|
||||||
{
|
|
||||||
Task GiveRewards(GiveRewardsCommand rewards);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RewardsApi
|
|
||||||
{
|
|
||||||
private readonly HttpListener listener = new HttpListener();
|
|
||||||
private readonly TaskFactory taskFactory = new TaskFactory();
|
|
||||||
private readonly IDiscordRoleController roleController;
|
|
||||||
private CancellationTokenSource cts = new CancellationTokenSource();
|
|
||||||
|
|
||||||
public RewardsApi(IDiscordRoleController roleController)
|
|
||||||
{
|
|
||||||
this.roleController = roleController;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
cts = new CancellationTokenSource();
|
|
||||||
var uri = $"http://*:{Program.Config.RewardApiPort}/";
|
|
||||||
listener.Prefixes.Add(uri);
|
|
||||||
listener.Start();
|
|
||||||
taskFactory.Run(ConnectionDispatcher, nameof(ConnectionDispatcher));
|
|
||||||
Program.Log.Log($"Reward API listening on '{uri}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
listener.Stop();
|
|
||||||
cts.Cancel();
|
|
||||||
taskFactory.WaitAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ConnectionDispatcher()
|
|
||||||
{
|
|
||||||
while (!cts.Token.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
var wait = listener.GetContextAsync();
|
|
||||||
wait.Wait(cts.Token);
|
|
||||||
if (wait.IsCompletedSuccessfully)
|
|
||||||
{
|
|
||||||
taskFactory.Run(() =>
|
|
||||||
{
|
|
||||||
var context = wait.Result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HandleConnection(context).Wait();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Program.Log.Error("Exception during HTTP handler: " + ex);
|
|
||||||
}
|
|
||||||
}, nameof(HandleConnection));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleConnection(HttpListenerContext context)
|
|
||||||
{
|
|
||||||
using var reader = new StreamReader(context.Request.InputStream);
|
|
||||||
var content = reader.ReadToEnd();
|
|
||||||
|
|
||||||
if (content == "Ping")
|
|
||||||
{
|
|
||||||
using var writer = new StreamWriter(context.Response.OutputStream);
|
|
||||||
writer.Write("Pong");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!content.StartsWith("{")) return;
|
|
||||||
var rewards = JsonConvert.DeserializeObject<GiveRewardsCommand>(content);
|
|
||||||
if (rewards != null)
|
|
||||||
{
|
|
||||||
await ProcessRewards(rewards);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ProcessRewards(GiveRewardsCommand rewards)
|
|
||||||
{
|
|
||||||
await roleController.GiveRewards(rewards);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,13 +4,13 @@ using DiscordRewards;
|
|||||||
|
|
||||||
namespace BiblioTech.Rewards
|
namespace BiblioTech.Rewards
|
||||||
{
|
{
|
||||||
public class RoleController : IDiscordRoleController
|
public class RoleDriver : IDiscordRoleDriver
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient client;
|
private readonly DiscordSocketClient client;
|
||||||
private readonly SocketTextChannel? rewardsChannel;
|
private readonly SocketTextChannel? rewardsChannel;
|
||||||
private readonly RewardRepo repo = new RewardRepo();
|
private readonly RewardRepo repo = new RewardRepo();
|
||||||
|
|
||||||
public RoleController(DiscordSocketClient client)
|
public RoleDriver(DiscordSocketClient client)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
@ -107,7 +107,13 @@ namespace BiblioTech.Rewards
|
|||||||
|
|
||||||
private SocketGuild GetGuild()
|
private SocketGuild GetGuild()
|
||||||
{
|
{
|
||||||
return client.Guilds.Single(g => g.Name == Program.Config.ServerName);
|
var guild = client.Guilds.SingleOrDefault(g => g.Name == Program.Config.ServerName);
|
||||||
|
if (guild == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Unable to find guild by name: '{Program.Config.ServerName}'. " +
|
||||||
|
$"Known guilds: [{string.Join(",", client.Guilds.Select(g => g.Name))}]");
|
||||||
|
}
|
||||||
|
return guild;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
using DiscordRewards;
|
using CodexContractsPlugin.Marketplace;
|
||||||
|
using DiscordRewards;
|
||||||
using Logging;
|
using Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -17,13 +18,30 @@ namespace TestNetRewarder
|
|||||||
|
|
||||||
public async Task<bool> IsOnline()
|
public async Task<bool> IsOnline()
|
||||||
{
|
{
|
||||||
return await HttpPost("Ping") == "Ping";
|
var result = await HttpGet();
|
||||||
|
log.Log("Is DiscordBot online: " + result);
|
||||||
|
return result == "Pong";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendRewards(GiveRewardsCommand command)
|
public async Task<bool> SendRewards(GiveRewardsCommand command)
|
||||||
{
|
{
|
||||||
if (command == null || command.Rewards == null || !command.Rewards.Any()) return;
|
if (command == null || command.Rewards == null || !command.Rewards.Any()) return false;
|
||||||
await HttpPost(JsonConvert.SerializeObject(command));
|
return await HttpPost(JsonConvert.SerializeObject(command)) == "OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> HttpGet()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var client = new HttpClient();
|
||||||
|
var response = await client.GetAsync(GetUrl());
|
||||||
|
return await response.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
log.Error(ex.ToString());
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> HttpPost(string content)
|
private async Task<string> HttpPost(string content)
|
||||||
@ -43,7 +61,7 @@ namespace TestNetRewarder
|
|||||||
|
|
||||||
private string GetUrl()
|
private string GetUrl()
|
||||||
{
|
{
|
||||||
return $"{configuration.DiscordHost}:{configuration.DiscordPort}";
|
return $"{configuration.DiscordHost}:{configuration.DiscordPort}/api/reward";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,14 @@ namespace TestNetRewarder
|
|||||||
|
|
||||||
if (outgoingRewards.Any())
|
if (outgoingRewards.Any())
|
||||||
{
|
{
|
||||||
await SendRewardsCommand(outgoingRewards);
|
if (!await SendRewardsCommand(outgoingRewards))
|
||||||
|
{
|
||||||
|
log.Error("Failed to send reward command.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendRewardsCommand(List<RewardUsersCommand> outgoingRewards)
|
private async Task<bool> SendRewardsCommand(List<RewardUsersCommand> outgoingRewards)
|
||||||
{
|
{
|
||||||
var cmd = new GiveRewardsCommand
|
var cmd = new GiveRewardsCommand
|
||||||
{
|
{
|
||||||
@ -56,7 +59,7 @@ namespace TestNetRewarder
|
|||||||
};
|
};
|
||||||
|
|
||||||
log.Debug("Sending rewards: " + JsonConvert.SerializeObject(cmd));
|
log.Debug("Sending rewards: " + JsonConvert.SerializeObject(cmd));
|
||||||
await Program.BotClient.SendRewards(cmd);
|
return await Program.BotClient.SendRewards(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessReward(List<RewardUsersCommand> outgoingRewards, RewardConfig reward, ChainState chainState)
|
private void ProcessReward(List<RewardUsersCommand> outgoingRewards, RewardConfig reward, ChainState chainState)
|
||||||
|
@ -59,6 +59,7 @@ namespace TestNetRewarder
|
|||||||
|
|
||||||
var blockNumber = gc.GethNode.GetSyncedBlockNumber();
|
var blockNumber = gc.GethNode.GetSyncedBlockNumber();
|
||||||
if (blockNumber == null || blockNumber < 1) throw new Exception("Geth connection failed.");
|
if (blockNumber == null || blockNumber < 1) throw new Exception("Geth connection failed.");
|
||||||
|
Log.Log("Geth OK. Block number: " + blockNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task EnsureBotOnline()
|
private static async Task EnsureBotOnline()
|
||||||
|
@ -33,6 +33,7 @@ namespace TestNetRewarder
|
|||||||
// Wait for the entire time segment to be in the past.
|
// Wait for the entire time segment to be in the past.
|
||||||
var delay = (end - now).Add(TimeSpan.FromSeconds(3));
|
var delay = (end - now).Add(TimeSpan.FromSeconds(3));
|
||||||
waited = true;
|
waited = true;
|
||||||
|
log.Log($"Waiting till time segment is in the past... {Time.FormatDuration(delay)}");
|
||||||
await Task.Delay(delay, Program.CancellationToken);
|
await Task.Delay(delay, Program.CancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
Tools/TestNetRewarder/build-docker.bat
Normal file
2
Tools/TestNetRewarder/build-docker.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
docker build -f docker/Dockerfile -t thatbenbierens/codex-rewardbot:initial ../..
|
||||||
|
docker push thatbenbierens/codex-rewardbot:initial
|
Loading…
x
Reference in New Issue
Block a user