Skip to content

Commit bca0002

Browse files
committed
simplify rate_limit_numbers by flattening the structure. just map message type -> rate limits
1 parent 97baacf commit bca0002

File tree

3 files changed

+185
-257
lines changed

3 files changed

+185
-257
lines changed

chia/_tests/core/server/test_rate_limits.py

Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from dataclasses import dataclass
4-
from typing import Any
4+
from typing import Union
55

66
import pytest
77
from chia_rs.sized_ints import uint32
@@ -13,8 +13,7 @@
1313
from chia.protocols.outbound_message import make_msg
1414
from chia.protocols.protocol_message_types import ProtocolMessageTypes
1515
from chia.protocols.shared_protocol import Capability
16-
from chia.server.rate_limit_numbers import RLSettings, compose_rate_limits, get_rate_limits_to_use
17-
from chia.server.rate_limit_numbers import rate_limits as rl_numbers
16+
from chia.server.rate_limit_numbers import RLSettings, Unlimited, get_rate_limits_to_use
1817
from chia.server.rate_limits import RateLimiter
1918
from chia.server.server import ChiaServer
2019
from chia.server.ws_connection import WSChiaConnection
@@ -65,39 +64,20 @@ async def test_limits_v2(incoming: bool, tx_msg: bool, limit_size: bool, monkeyp
6564
message_data = b"\0" * 1024
6665
msg_type = ProtocolMessageTypes.new_transaction
6766

68-
limits: dict[str, Any] = {}
67+
limits: dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]]
6968

7069
if limit_size:
71-
limits.update(
72-
{
73-
# this is the rate limit across all (non-tx) messages
74-
"non_tx_freq": count * 2,
75-
# this is the byte size limit across all (non-tx) messages
76-
"non_tx_max_total_size": count * len(message_data),
77-
}
78-
)
70+
agg_limit = RLSettings(False, count * 2, 1024, count * len(message_data))
7971
else:
80-
limits.update(
81-
{
82-
# this is the rate limit across all (non-tx) messages
83-
"non_tx_freq": count,
84-
# this is the byte size limit across all (non-tx) messages
85-
"non_tx_max_total_size": count * 2 * len(message_data),
86-
}
87-
)
72+
agg_limit = RLSettings(False, count, 1024, count * 2 * len(message_data))
8873

8974
if limit_size:
90-
rate_limit = {msg_type: RLSettings(count * 2, 1024, count * len(message_data))}
75+
limits = {msg_type: RLSettings(not tx_msg, count * 2, 1024, count * len(message_data))}
9176
else:
92-
rate_limit = {msg_type: RLSettings(count, 1024, count * 2 * len(message_data))}
77+
limits = {msg_type: RLSettings(not tx_msg, count, 1024, count * 2 * len(message_data))}
9378

94-
if tx_msg:
95-
limits.update({"rate_limits_tx": rate_limit, "rate_limits_other": {}})
96-
else:
97-
limits.update({"rate_limits_other": rate_limit, "rate_limits_tx": {}})
98-
99-
def mock_get_limits(*args, **kwargs) -> dict[str, Any]:
100-
return limits
79+
def mock_get_limits(*args, **kwargs) -> tuple[dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]], RLSettings]:
80+
return limits, agg_limit
10181

10282
import chia.server.rate_limits
10383

@@ -325,18 +305,18 @@ async def test_too_many_outgoing_messages():
325305
# Too many messages
326306
r = RateLimiter(incoming=False, get_time=lambda: 0)
327307
new_peers_message = make_msg(ProtocolMessageTypes.respond_peers, bytes([1]))
328-
non_tx_freq = get_rate_limits_to_use(rl_v2, rl_v2)["non_tx_freq"]
308+
_, agg_limit = get_rate_limits_to_use(rl_v2, rl_v2)
329309

330310
passed = 0
331311
blocked = 0
332-
for i in range(non_tx_freq):
312+
for i in range(agg_limit.frequency):
333313
if r.process_msg_and_check(new_peers_message, rl_v2, rl_v2) is None:
334314
passed += 1
335315
else:
336316
blocked += 1
337317

338318
assert passed == 10
339-
assert blocked == non_tx_freq - passed
319+
assert blocked == agg_limit.frequency - passed
340320

341321
# ensure that *another* message type is not blocked because of this
342322

@@ -349,18 +329,18 @@ async def test_too_many_incoming_messages():
349329
# Too many messages
350330
r = RateLimiter(incoming=True, get_time=lambda: 0)
351331
new_peers_message = make_msg(ProtocolMessageTypes.respond_peers, bytes([1]))
352-
non_tx_freq = get_rate_limits_to_use(rl_v2, rl_v2)["non_tx_freq"]
332+
_, agg_limit = get_rate_limits_to_use(rl_v2, rl_v2)
353333

354334
passed = 0
355335
blocked = 0
356-
for i in range(non_tx_freq):
336+
for i in range(agg_limit.frequency):
357337
if r.process_msg_and_check(new_peers_message, rl_v2, rl_v2) is None:
358338
passed += 1
359339
else:
360340
blocked += 1
361341

362342
assert passed == 10
363-
assert blocked == non_tx_freq - passed
343+
assert blocked == agg_limit.frequency - passed
364344

365345
# ensure that other message types *are* blocked because of this
366346

@@ -432,39 +412,13 @@ async def test_different_versions(node_with_params, node_with_params_b, self_hos
432412
# The following code checks whether all of the runs resulted in the same number of items in "rate_limits_tx",
433413
# which would mean the same rate limits are always used. This should not happen, since two nodes with V2
434414
# will use V2.
435-
total_tx_msg_count = len(
436-
get_rate_limits_to_use(a_con.local_capabilities, a_con.peer_capabilities)["rate_limits_tx"]
437-
)
415+
total_tx_msg_count = len(get_rate_limits_to_use(a_con.local_capabilities, a_con.peer_capabilities))
438416

439417
test_different_versions_results.append(total_tx_msg_count)
440418
if len(test_different_versions_results) >= 4:
441419
assert len(set(test_different_versions_results)) >= 2
442420

443421

444-
@pytest.mark.anyio
445-
async def test_compose():
446-
rl_1 = rl_numbers[1]
447-
rl_2 = rl_numbers[2]
448-
assert ProtocolMessageTypes.respond_children in rl_1["rate_limits_other"]
449-
assert ProtocolMessageTypes.respond_children not in rl_1["rate_limits_tx"]
450-
assert ProtocolMessageTypes.respond_children not in rl_2["rate_limits_other"]
451-
assert ProtocolMessageTypes.respond_children in rl_2["rate_limits_tx"]
452-
453-
assert ProtocolMessageTypes.request_block in rl_1["rate_limits_other"]
454-
assert ProtocolMessageTypes.request_block not in rl_1["rate_limits_tx"]
455-
assert ProtocolMessageTypes.request_block not in rl_2["rate_limits_other"]
456-
assert ProtocolMessageTypes.request_block not in rl_2["rate_limits_tx"]
457-
458-
comps = compose_rate_limits(rl_1, rl_2)
459-
# v2 limits are used if present
460-
assert ProtocolMessageTypes.respond_children not in comps["rate_limits_other"]
461-
assert ProtocolMessageTypes.respond_children in comps["rate_limits_tx"]
462-
463-
# Otherwise, fall back to v1
464-
assert ProtocolMessageTypes.request_block in rl_1["rate_limits_other"]
465-
assert ProtocolMessageTypes.request_block not in rl_1["rate_limits_tx"]
466-
467-
468422
@pytest.mark.anyio
469423
@pytest.mark.parametrize(
470424
"msg_type, size",

0 commit comments

Comments
 (0)