Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
Fix node speed does not update (NethermindEth#4646)
Browse files Browse the repository at this point in the history
  • Loading branch information
asdacap authored and Andrew-Pohl committed Oct 7, 2022
1 parent c963d87 commit 9b8e685
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 28 deletions.
50 changes: 28 additions & 22 deletions src/Nethermind/Nethermind.Network.Stats/NodeStatsLight.cs
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

Expand All @@ -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;
Expand All @@ -54,10 +54,11 @@ public class NodeStatsLight : INodeStats

private static readonly int _statsLength = FastEnum.GetValues<NodeStatsEventType>().Count;

public NodeStatsLight(Node node)
public NodeStatsLight(Node node, decimal latestSpeedWeight = 0.25m)
{
_statCountersArray = new int[_statsLength];
_statsParameters = StatsParameters.Instance;
_latestSpeedWeight = latestSpeedWeight;
Node = node;
}

Expand Down Expand Up @@ -152,29 +153,34 @@ 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);
}
}
}

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
Expand All @@ -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()
});
}
Expand Down
18 changes: 12 additions & 6 deletions src/Nethermind/Nethermind.Network.Test/NodeStatsTests.cs
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

Expand Down Expand Up @@ -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);
Expand All @@ -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]
Expand Down

0 comments on commit 9b8e685

Please sign in to comment.