From 117a30bb829051da76bcacd2ed1b6364689926bb Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 30 May 2024 10:55:33 +0200 Subject: [PATCH] wip --- .../RewarderBotContainerRecipe.cs | 2 +- Tests/CodexTests/CodexTests.csproj | 1 + .../UtilityTests/DiscordBotTests.cs | 143 ++++++++++++++---- 3 files changed, 112 insertions(+), 34 deletions(-) diff --git a/ProjectPlugins/CodexDiscordBotPlugin/RewarderBotContainerRecipe.cs b/ProjectPlugins/CodexDiscordBotPlugin/RewarderBotContainerRecipe.cs index ae31e696..8bf4344d 100644 --- a/ProjectPlugins/CodexDiscordBotPlugin/RewarderBotContainerRecipe.cs +++ b/ProjectPlugins/CodexDiscordBotPlugin/RewarderBotContainerRecipe.cs @@ -7,7 +7,7 @@ namespace CodexDiscordBotPlugin public class RewarderBotContainerRecipe : ContainerRecipeFactory { public override string AppName => "discordbot-rewarder"; - public override string Image => "codexstorage/codex-rewarderbot:sha-2ab84e2"; + public override string Image => "codexstorage/codex-rewarderbot:sha-ccc6c81"; protected override void Initialize(StartupConfig startupConfig) { diff --git a/Tests/CodexTests/CodexTests.csproj b/Tests/CodexTests/CodexTests.csproj index 10d1a225..4a9a3edb 100644 --- a/Tests/CodexTests/CodexTests.csproj +++ b/Tests/CodexTests/CodexTests.csproj @@ -19,6 +19,7 @@ + diff --git a/Tests/CodexTests/UtilityTests/DiscordBotTests.cs b/Tests/CodexTests/UtilityTests/DiscordBotTests.cs index 671d6c07..29403eb2 100644 --- a/Tests/CodexTests/UtilityTests/DiscordBotTests.cs +++ b/Tests/CodexTests/UtilityTests/DiscordBotTests.cs @@ -37,17 +37,19 @@ namespace CodexTests.UtilityTests StartHosts(geth, contracts); - StartRewarderBot(gethInfo, botContainer); + var rewarderContainer = StartRewarderBot(gethInfo, botContainer); var client = StartClient(geth, contracts); - var purchaseContract = ClientPurchasesStorage(client); - var apiCalls = new RewardApiCalls(Ci, botContainer); apiCalls.Start(OnCommand); + var rewarderLog = new RewarderLogMonitor(Ci, rewarderContainer.Containers.Single()); + rewarderLog.Start(l => Log("Rewarder ChainState: " + l)); + var purchaseContract = ClientPurchasesStorage(client); purchaseContract.WaitForStorageContractFinished(); + rewarderLog.Stop(); apiCalls.Stop(); monitor.Stop(); @@ -118,9 +120,9 @@ namespace CodexTests.UtilityTests return node; } - private void StartRewarderBot(DiscordBotGethInfo gethInfo, RunningContainer botContainer) + private RunningPod StartRewarderBot(DiscordBotGethInfo gethInfo, RunningContainer botContainer) { - Ci.DeployRewarderBot(new RewarderBotStartupConfig( + return Ci.DeployRewarderBot(new RewarderBotStartupConfig( name: "rewarder-bot", discordBotHost: botContainer.GetInternalAddress(DiscordBotContainerRecipe.RewardsPort).Host, discordBotPort: botContainer.GetInternalAddress(DiscordBotContainerRecipe.RewardsPort).Port, @@ -238,22 +240,113 @@ namespace CodexTests.UtilityTests public class RewardApiCalls { - private readonly CoreInterface ci; - private readonly RunningContainer botContainer; + private readonly ContainerFileMonitor monitor; private readonly Dictionary commands = new Dictionary(); - private readonly CancellationTokenSource cts = new CancellationTokenSource(); - private Task worker = Task.CompletedTask; - private Action onCommand = c => { }; public RewardApiCalls(CoreInterface ci, RunningContainer botContainer) { - this.ci = ci; - this.botContainer = botContainer; + monitor = new ContainerFileMonitor(ci, botContainer, "/app/datapath/logs/discordbot.log"); } public void Start(Action onCommand) { - this.onCommand = onCommand; + monitor.Start(line => ParseLine(line, onCommand)); + } + + public void Stop() + { + monitor.Stop(); + } + + private void ParseLine(string line, Action onCommand) + { + try + { + var timestamp = line.Substring(0, 30); + if (commands.ContainsKey(timestamp)) return; + var json = line.Substring(31); + + var cmd = JsonConvert.DeserializeObject(json); + if (cmd != null) + { + commands.Add(timestamp, cmd); + onCommand(cmd); + } + } + catch + { + } + } + } + + public class RewarderLogMonitor + { + private readonly ContainerFileMonitor monitor; + private readonly Dictionary commands = new Dictionary(); + + public RewarderLogMonitor(CoreInterface ci, RunningContainer botContainer) + { + monitor = new ContainerFileMonitor(ci, botContainer, "/app/datapath/logs/testnetrewarder.log"); + } + + public void Start(Action onCommand) + { + monitor.Start(l => ProcessLine(l, onCommand)); + } + + public void Stop() + { + monitor.Stop(); + } + + private void ProcessLine(string line, Action log) + { + // Processing chain state: ' + // NewRequests: [] + // FulfilledE: [] + // CancelledE: [] + // FilledE: [] + // FreedE: [] + // Historic: [{"Request":{"RequestId":"hvWlli4gHP5tUJoG5b8zh3tMBIr0wpcr/lHgIU/KRmU=","ClientAddress":{"Address":"0x760e722469cdeb086b78edd2b4b670621f43a923"},"Client":"0x760e722469Cdeb086b78EdD2b4b670621F43a923","Ask":{"Slots":4,"SlotSize":33554432,"Duration":360,"ProofProbability":5,"Reward":2,"Collateral":10,"MaxSlotLoss":2},"Content":{"Cid":"zDvZRwzm8DzbqdUcy7gS1wFKAsBjUHTQEUt1am1L6XGEWtsJ5U2X","MerkleRoot":"/KjFr+FezQ8m3huhdaPDy6zVgZs3ODtfE78K5eyieQo="},"Expiry":300,"Nonce":"2tANtfgVcMBuLLxe+4MbxMFWWO36Yv+l2yC4tpqdelI="},"Hosts":[{"Address":"0x0000000000000000000000000000000000000000"},{"Address":"0x0000000000000000000000000000000000000000"},{"Address":"0x0000000000000000000000000000000000000000"},{"Address":"0x0000000000000000000000000000000000000000"}],"State":"New"}] + // ' + + if (!line.Contains("Processing chain state: ")) return; + + log(Between(line, "'")); + //var tokens = state.Split("Historic: ", StringSplitOptions.RemoveEmptyEntries); + //var historics = JsonConvert.DeserializeObject(tokens[1]); + + //log(tokens[0] + " historic: " + string.Join(",", historics!.Select(h => h.Request.RequestId + " = " + h.State))); + } + + private string Between(string s, string lim) + { + var start = s.IndexOf(lim) + lim.Length; + var end = s.LastIndexOf(lim); + return s.Substring(start, end - start); + } + } + + public class ContainerFileMonitor + { + private readonly CoreInterface ci; + private readonly RunningContainer botContainer; + private readonly string filePath; + private readonly CancellationTokenSource cts = new CancellationTokenSource(); + private readonly List seenLines = new List(); + private Task worker = Task.CompletedTask; + private Action onNewLine = c => { }; + + public ContainerFileMonitor(CoreInterface ci, RunningContainer botContainer, string filePath) + { + this.ci = ci; + this.botContainer = botContainer; + this.filePath = filePath; + } + + public void Start(Action onNewLine) + { + this.onNewLine = onNewLine; worker = Task.Run(Worker); } @@ -276,32 +369,16 @@ namespace CodexTests.UtilityTests Thread.Sleep(TimeSpan.FromSeconds(10)); if (cts.IsCancellationRequested) return; - var botLog = ci.ExecuteContainerCommand(botContainer, "cat", "/app/datapath/logs/discordbot.log"); + var botLog = ci.ExecuteContainerCommand(botContainer, "cat", filePath); var lines = botLog.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { - AddToCache(line); - } - } - - private void AddToCache(string line) - { - try - { - var timestamp = line.Substring(0, 30); - if (commands.ContainsKey(timestamp)) return; - var json = line.Substring(31); - - var cmd = JsonConvert.DeserializeObject(json); - if (cmd != null) + if (!seenLines.Contains(line)) { - commands.Add(timestamp, cmd); - onCommand(cmd); + seenLines.Add(line); + onNewLine(line); } } - catch - { - } } }