From 9b8e68592bfe6f6b76e7a9de53fcd507da1e582c Mon Sep 17 00:00:00 2001 From: Amirul Ashraf Date: Thu, 29 Sep 2022 21:35:09 +0800 Subject: [PATCH] Fix node speed does not update (#4646) --- .../NodeStatsLight.cs | 50 +++++++++++-------- .../Nethermind.Network.Test/NodeStatsTests.cs | 18 ++++--- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/Nethermind/Nethermind.Network.Stats/NodeStatsLight.cs b/src/Nethermind/Nethermind.Network.Stats/NodeStatsLight.cs index a0de552c0d71..2c86cc58ddad 100644 --- a/src/Nethermind/Nethermind.Network.Stats/NodeStatsLight.cs +++ b/src/Nethermind/Nethermind.Network.Stats/NodeStatsLight.cs @@ -1,16 +1,16 @@ // Copyright (c) 2021 Demerzel Solutions Limited // This file is part of the Nethermind library. -// +// // The Nethermind library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // The Nethermind library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. -// +// // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . @@ -28,12 +28,12 @@ public class NodeStatsLight : INodeStats { private readonly StatsParameters _statsParameters; - private long _headersTransferSpeedEventCount; - private long _bodiesTransferSpeedEventCount; - private long _receiptsTransferSpeedEventCount; - private long _nodesTransferSpeedEventCount; - private long _snapRangesTransferSpeedEventCount; - private long _latencyEventCount; + // How much weight to put on latest speed. + // 1.0m means that the reported speed will always replaced with latest speed. + // 0.5m means that the reported speed will be (oldSpeed + newSpeed)/2; + // 0.25m here means that the latest weight affect the stored weight a bit for every report, resulting in a smoother + // modification to account for jitter. + private readonly decimal _latestSpeedWeight; private decimal? _averageNodesTransferSpeed; private decimal? _averageHeadersTransferSpeed; @@ -54,10 +54,11 @@ public class NodeStatsLight : INodeStats private static readonly int _statsLength = FastEnum.GetValues().Count; - public NodeStatsLight(Node node) + public NodeStatsLight(Node node, decimal latestSpeedWeight = 0.25m) { _statCountersArray = new int[_statsLength]; _statsParameters = StatsParameters.Instance; + _latestSpeedWeight = latestSpeedWeight; Node = node; } @@ -152,22 +153,22 @@ public void AddTransferSpeedCaptureEvent(TransferSpeedType transferSpeedType, lo switch (transferSpeedType) { case TransferSpeedType.Latency: - _averageLatency = ((_latencyEventCount * (_averageLatency ?? 0)) + bytesPerMillisecond) / (++_latencyEventCount); + UpdateValue(ref _averageLatency, bytesPerMillisecond); break; case TransferSpeedType.NodeData: - _averageNodesTransferSpeed = ((_nodesTransferSpeedEventCount * (_averageNodesTransferSpeed ?? 0)) + bytesPerMillisecond) / (++_nodesTransferSpeedEventCount); + UpdateValue(ref _averageNodesTransferSpeed, bytesPerMillisecond); break; case TransferSpeedType.Headers: - _averageHeadersTransferSpeed = ((_headersTransferSpeedEventCount * (_averageHeadersTransferSpeed ?? 0)) + bytesPerMillisecond) / (++_headersTransferSpeedEventCount); + UpdateValue(ref _averageHeadersTransferSpeed, bytesPerMillisecond); break; case TransferSpeedType.Bodies: - _averageBodiesTransferSpeed = ((_bodiesTransferSpeedEventCount * (_averageBodiesTransferSpeed ?? 0)) + bytesPerMillisecond) / (++_bodiesTransferSpeedEventCount); + UpdateValue(ref _averageBodiesTransferSpeed, bytesPerMillisecond); break; case TransferSpeedType.Receipts: - _averageReceiptsTransferSpeed = ((_receiptsTransferSpeedEventCount * (_averageReceiptsTransferSpeed ?? 0)) + bytesPerMillisecond) / (++_receiptsTransferSpeedEventCount); + UpdateValue(ref _averageReceiptsTransferSpeed, bytesPerMillisecond); break; case TransferSpeedType.SnapRanges: - _averageSnapRangesTransferSpeed = ((_snapRangesTransferSpeedEventCount * (_averageSnapRangesTransferSpeed ?? 0)) + bytesPerMillisecond) / (++_snapRangesTransferSpeedEventCount); + UpdateValue(ref _averageSnapRangesTransferSpeed, bytesPerMillisecond); break; default: throw new ArgumentOutOfRangeException(nameof(transferSpeedType), transferSpeedType, null); @@ -175,6 +176,11 @@ public void AddTransferSpeedCaptureEvent(TransferSpeedType transferSpeedType, lo } } + private void UpdateValue(ref decimal? currentValue, decimal newValue) + { + currentValue = ((currentValue ?? newValue) * ( 1.0m - _latestSpeedWeight)) + (newValue * _latestSpeedWeight); + } + public long? GetAverageTransferSpeed(TransferSpeedType transferSpeedType) { return (long?)(transferSpeedType switch @@ -193,12 +199,12 @@ public string GetPaddedAverageTransferSpeed(TransferSpeedType transferSpeedType) { return (transferSpeedType switch { - TransferSpeedType.Latency => $"{_averageLatency ?? 0,5:0}", - TransferSpeedType.NodeData => $"{_averageNodesTransferSpeed ?? 0,5:0}", - TransferSpeedType.Headers => $"{_averageHeadersTransferSpeed ?? 0,5:0}", - TransferSpeedType.Bodies => $"{_averageBodiesTransferSpeed ?? 0,5:0}", - TransferSpeedType.Receipts => $"{_averageReceiptsTransferSpeed ?? 0,5:0}", - TransferSpeedType.SnapRanges => $"{_averageSnapRangesTransferSpeed ?? 0,5:0}", + TransferSpeedType.Latency => $"{_averageLatency ?? -1,5:0}", + TransferSpeedType.NodeData => $"{_averageNodesTransferSpeed ?? -1,5:0}", + TransferSpeedType.Headers => $"{_averageHeadersTransferSpeed ?? -1,5:0}", + TransferSpeedType.Bodies => $"{_averageBodiesTransferSpeed ?? -1,5:0}", + TransferSpeedType.Receipts => $"{_averageReceiptsTransferSpeed ?? -1,5:0}", + TransferSpeedType.SnapRanges => $"{_averageSnapRangesTransferSpeed ?? -1,5:0}", _ => throw new ArgumentOutOfRangeException() }); } diff --git a/src/Nethermind/Nethermind.Network.Test/NodeStatsTests.cs b/src/Nethermind/Nethermind.Network.Test/NodeStatsTests.cs index 349299658141..ff3b6b044ce4 100644 --- a/src/Nethermind/Nethermind.Network.Test/NodeStatsTests.cs +++ b/src/Nethermind/Nethermind.Network.Test/NodeStatsTests.cs @@ -1,16 +1,16 @@ // Copyright (c) 2021 Demerzel Solutions Limited // This file is part of the Nethermind library. -// +// // The Nethermind library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // The Nethermind library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. -// +// // You should have received a copy of the GNU Lesser General Public License // along with the Nethermind. If not, see . @@ -42,7 +42,7 @@ public void Initialize() [TestCase(TransferSpeedType.NodeData)] public void TransferSpeedCaptureTest(TransferSpeedType speedType) { - _nodeStats = new NodeStatsLight(_node); + _nodeStats = new NodeStatsLight(_node, 0.5m); _nodeStats.AddTransferSpeedCaptureEvent(speedType, 30); _nodeStats.AddTransferSpeedCaptureEvent(speedType, 51); @@ -59,10 +59,16 @@ public void TransferSpeedCaptureTest(TransferSpeedType speedType) _nodeStats.AddTransferSpeedCaptureEvent(speedType, 133); var av = _nodeStats.GetAverageTransferSpeed(speedType); - Assert.AreEqual(102, av); + Assert.AreEqual(122, av); var paddedAv = _nodeStats.GetPaddedAverageTransferSpeed(speedType); - Assert.AreEqual(" 102", paddedAv); + Assert.AreEqual(" 122", paddedAv); + + _nodeStats.AddTransferSpeedCaptureEvent(speedType, 0); + _nodeStats.AddTransferSpeedCaptureEvent(speedType, 0); + + av = _nodeStats.GetAverageTransferSpeed(speedType); + Assert.AreEqual(30, av); } [Test]