Skip to content

Commit 0821062

Browse files
committed
simplify rate_limit_numbers by flattening the structure. just map message type -> rate limits
1 parent 071a449 commit 0821062

File tree

3 files changed

+186
-259
lines changed

3 files changed

+186
-259
lines changed

chia/_tests/core/server/test_rate_limits.py

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any
3+
from typing import Union
44

55
import pytest
66
from chia_rs.sized_ints import uint32
@@ -11,8 +11,7 @@
1111
from chia.protocols.outbound_message import make_msg
1212
from chia.protocols.protocol_message_types import ProtocolMessageTypes
1313
from chia.protocols.shared_protocol import Capability
14-
from chia.server.rate_limit_numbers import RLSettings, compose_rate_limits, get_rate_limits_to_use
15-
from chia.server.rate_limit_numbers import rate_limits as rl_numbers
14+
from chia.server.rate_limit_numbers import RLSettings, Unlimited, get_rate_limits_to_use
1615
from chia.server.rate_limits import RateLimiter
1716
from chia.server.server import ChiaServer
1817
from chia.server.ws_connection import WSChiaConnection
@@ -75,46 +74,26 @@ async def test_limits_v2(incoming: bool, tx_msg: bool, cumulative_size: bool, mo
7574
message_data = b"0" * 1024
7675
msg_type = ProtocolMessageTypes.new_transaction
7776

78-
limits: dict[str, Any] = {}
79-
8077
if cumulative_size:
81-
limits.update(
82-
{
83-
# this is the rate limit across all (non-tx) messages
84-
"non_tx_freq": 2000,
85-
# this is the byte size limit across all (non-tx) messages
86-
"non_tx_max_total_size": 1000 * 1024,
87-
}
88-
)
78+
agg_limit = RLSettings(False, 2000, 1000 * 1024, 1000 * 1024)
8979
else:
90-
limits.update(
91-
{
92-
# this is the rate limit across all (non-tx) messages
93-
"non_tx_freq": 1000,
94-
# this is the byte size limit across all (non-tx) messages
95-
"non_tx_max_total_size": 100 * 1024 * 1024,
96-
}
97-
)
80+
agg_limit = RLSettings(False, 1000, 100 * 1024 * 1024, 100 * 1024 * 1024)
9881

82+
limits: dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]]
9983
if cumulative_size:
100-
rate_limit = {msg_type: RLSettings(2000, 1024, 1000 * 1024)}
101-
else:
102-
rate_limit = {msg_type: RLSettings(1000, 1024, 1000 * 1024 * 1024)}
103-
104-
if tx_msg:
105-
limits.update({"rate_limits_tx": rate_limit, "rate_limits_other": {}})
84+
limits = {msg_type: RLSettings(not tx_msg, 2000, 1024, 1000 * 1024)}
10685
else:
107-
limits.update({"rate_limits_other": rate_limit, "rate_limits_tx": {}})
86+
limits = {msg_type: RLSettings(not tx_msg, 1000, 1024, 1000 * 1024 * 1024)}
10887

109-
def mock_get_limits(*args, **kwargs) -> dict[str, Any]:
110-
return limits
88+
def mock_get_limits(*args, **kwargs) -> tuple[dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]], RLSettings]:
89+
return limits, agg_limit
11190

11291
import chia
11392

11493
monkeypatch.setattr(chia.server.rate_limits, "get_rate_limits_to_use", mock_get_limits)
11594

11695
r = RateLimiter(incoming=incoming)
117-
msg = make_msg(ProtocolMessageTypes.new_transaction, message_data)
96+
msg = make_msg(msg_type, message_data)
11897

11998
for i in range(count):
12099
assert r.process_msg_and_check(msg, rl_v2, rl_v2) is None
@@ -323,18 +302,18 @@ async def test_too_many_outgoing_messages(mock_timer):
323302
# Too many messages
324303
r = RateLimiter(incoming=False)
325304
new_peers_message = make_msg(ProtocolMessageTypes.respond_peers, bytes([1]))
326-
non_tx_freq = get_rate_limits_to_use(rl_v2, rl_v2)["non_tx_freq"]
305+
_, agg_limit = get_rate_limits_to_use(rl_v2, rl_v2)
327306

328307
passed = 0
329308
blocked = 0
330-
for i in range(non_tx_freq):
309+
for i in range(agg_limit.frequency):
331310
if r.process_msg_and_check(new_peers_message, rl_v2, rl_v2) is None:
332311
passed += 1
333312
else:
334313
blocked += 1
335314

336315
assert passed == 10
337-
assert blocked == non_tx_freq - passed
316+
assert blocked == agg_limit.frequency - passed
338317

339318
# ensure that *another* message type is not blocked because of this
340319

@@ -347,18 +326,18 @@ async def test_too_many_incoming_messages(mock_timer):
347326
# Too many messages
348327
r = RateLimiter(incoming=True)
349328
new_peers_message = make_msg(ProtocolMessageTypes.respond_peers, bytes([1]))
350-
non_tx_freq = get_rate_limits_to_use(rl_v2, rl_v2)["non_tx_freq"]
329+
_, agg_limit = get_rate_limits_to_use(rl_v2, rl_v2)
351330

352331
passed = 0
353332
blocked = 0
354-
for i in range(non_tx_freq):
333+
for i in range(agg_limit.frequency):
355334
if r.process_msg_and_check(new_peers_message, rl_v2, rl_v2) is None:
356335
passed += 1
357336
else:
358337
blocked += 1
359338

360339
assert passed == 10
361-
assert blocked == non_tx_freq - passed
340+
assert blocked == agg_limit.frequency - passed
362341

363342
# ensure that other message types *are* blocked because of this
364343

@@ -430,39 +409,13 @@ async def test_different_versions(node_with_params, node_with_params_b, self_hos
430409
# The following code checks whether all of the runs resulted in the same number of items in "rate_limits_tx",
431410
# which would mean the same rate limits are always used. This should not happen, since two nodes with V2
432411
# will use V2.
433-
total_tx_msg_count = len(
434-
get_rate_limits_to_use(a_con.local_capabilities, a_con.peer_capabilities)["rate_limits_tx"]
435-
)
412+
total_tx_msg_count = len(get_rate_limits_to_use(a_con.local_capabilities, a_con.peer_capabilities))
436413

437414
test_different_versions_results.append(total_tx_msg_count)
438415
if len(test_different_versions_results) >= 4:
439416
assert len(set(test_different_versions_results)) >= 2
440417

441418

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

0 commit comments

Comments
 (0)