Skip to content

Commit 8be8415

Browse files
authored
Merge branch 'master' into feature/execution-metrics-standardization
2 parents 88b20ab + ba117e5 commit 8be8415

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// SPDX-FileCopyrightText: 2026 Demerzel Solutions Limited
2+
// SPDX-License-Identifier: LGPL-3.0-only
3+
4+
using FluentAssertions;
5+
using Nethermind.Core.Collections;
6+
using Nethermind.Core.Test.Builders;
7+
using Nethermind.Network.P2P.Subprotocols.Snap;
8+
using Nethermind.Network.P2P.Subprotocols.Snap.Messages;
9+
using Nethermind.Serialization.Rlp;
10+
using Nethermind.State.Snap;
11+
using NUnit.Framework;
12+
13+
namespace Nethermind.Network.Test.P2P.Subprotocols.Snap.Messages;
14+
15+
[TestFixture, Parallelizable(ParallelScope.All)]
16+
public class SnapMessageLimitsTests
17+
{
18+
/// <summary>
19+
/// Response limits must be large enough that a valid message within
20+
/// <see cref="SnapMessageLimits.MaxResponseBytes"/> (3 MiB) never exceeds the limit.
21+
/// A too-low limit causes <see cref="RlpLimitException"/>, which disconnects and bans
22+
/// the peer for 15 minutes — silently killing SnapSync throughput.
23+
/// </summary>
24+
[TestCase(nameof(SnapMessageLimits.MaxResponseAccounts), SnapMessageLimits.MaxResponseAccounts, 40, TestName = "MaxResponseAccounts accommodates 3 MiB at ~40 bytes/account")]
25+
[TestCase(nameof(SnapMessageLimits.MaxResponseSlotsPerAccount), SnapMessageLimits.MaxResponseSlotsPerAccount, 36, TestName = "MaxResponseSlotsPerAccount accommodates 3 MiB at ~36 bytes/slot")]
26+
public void Response_limit_accommodates_max_response_bytes(string limitName, int limit, int minEntryBytes)
27+
{
28+
int maxTheoreticalItems = (int)(SnapMessageLimits.MaxResponseBytes / minEntryBytes);
29+
30+
limit.Should().BeGreaterThanOrEqualTo(maxTheoreticalItems,
31+
"{0} must accommodate the maximum item count that fits in a {1}-byte response at {2} bytes/entry",
32+
limitName, SnapMessageLimits.MaxResponseBytes, minEntryBytes);
33+
}
34+
35+
[Test]
36+
public void Roundtrip_AccountRange_at_40k_accounts()
37+
{
38+
const int count = 40_000;
39+
AccountRangeMessageSerializer serializer = new();
40+
41+
ArrayPoolList<PathWithAccount> accounts = new(count);
42+
for (int i = 0; i < count; i++)
43+
{
44+
accounts.Add(new PathWithAccount(TestItem.KeccakA, Build.An.Account.WithBalance(1).TestObject));
45+
}
46+
47+
AccountRangeMessage msg = new()
48+
{
49+
RequestId = 1,
50+
PathsWithAccounts = accounts,
51+
Proofs = EmptyByteArrayList.Instance,
52+
};
53+
54+
byte[] serialized = serializer.Serialize(msg);
55+
AccountRangeMessage deserialized = serializer.Deserialize(serialized);
56+
57+
deserialized.PathsWithAccounts.Count.Should().Be(count);
58+
}
59+
60+
[Test]
61+
public void Roundtrip_StorageRange_at_50k_slots()
62+
{
63+
const int slotCount = 50_000;
64+
StorageRangesMessageSerializer serializer = new();
65+
66+
ArrayPoolList<PathWithStorageSlot> slots = new(slotCount);
67+
for (int i = 0; i < slotCount; i++)
68+
{
69+
slots.Add(new PathWithStorageSlot(TestItem.KeccakA, Rlp.Encode(new byte[] { 0x01 }).Bytes));
70+
}
71+
72+
using StorageRangeMessage msg = new()
73+
{
74+
RequestId = 1,
75+
Slots = new ArrayPoolList<IOwnedReadOnlyList<PathWithStorageSlot>>(1) { slots },
76+
Proofs = new ByteArrayListAdapter(ArrayPoolList<byte[]>.Empty()),
77+
};
78+
79+
byte[] serialized = serializer.Serialize(msg);
80+
using StorageRangeMessage deserialized = serializer.Deserialize(serialized);
81+
82+
deserialized.Slots[0].Count.Should().Be(slotCount);
83+
}
84+
}

src/Nethermind/Nethermind.Network/P2P/Subprotocols/Snap/SnapMessageLimits.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ internal static class SnapMessageLimits
1414
public const int MaxRequestAccounts = 4_096;
1515
public const int MaxRequestPathGroups = 4_096;
1616
public const int MaxRequestPathsPerGroup = 1_024;
17-
public const int MaxResponseAccounts = 16_384;
18-
public const int MaxResponseSlotsPerAccount = 16_384;
17+
public const int MaxResponseAccounts = 131_072;
18+
public const int MaxResponseSlotsPerAccount = 131_072;
1919
public const long MaxResponseBytes = 3_145_728; // 3 MiB
2020

2121
public static readonly RlpLimit GetByteCodesHashesRlpLimit = RlpLimit.For<GetByteCodesMessage>(MaxRequestHashes, nameof(GetByteCodesMessage.Hashes));

0 commit comments

Comments
 (0)