Repository: Chia-Network/chia-blockchain
File: chia/server/rate_limit_numbers.py (Python)

Code before:
compose_rate_limits_cache: dict[int, dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]]] = {}


# this class is used to configure the *rate* limit for a message type. The
# limits are counts and size per 60 seconds.
@dataclasses.dataclass(frozen=True)
class RLSettings:
    # if true, messages affect and are limited by the per connection aggregate limiter,
    # which affects messages across message types
    aggregate_limit: bool
    frequency: int  # Max request per time period (ie 1 min)
    max_size: int  # Max size of each request
    max_total_size: Optional[int] = None  # Max cumulative size of all requests in that period


# this class is used to indicate that a message type is not subject to a rate
# limit, but just a per-message size limit. This may be appropriate for response
# messages that are implicitly limited by their corresponding request message
# Unlimited message types are also not subject to the overall limit across all
# messages (just like messages in the "tx" category)
@dataclasses.dataclass(frozen=True)
class Unlimited:
    max_size: int  # Max size of each request


aggregate_limit = RLSettings(False, 1000, 100 * 1024 * 1024 * 1024, 100 * 1024 * 1024 * 1024)


def get_rate_limits_to_use(
    our_capabilities: list[Capability], peer_capabilities: list[Capability]
) -> tuple[dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]], RLSettings]:
    # This will use the newest possible rate limits that both peers support. At this time there are only two
    # options, v1 and v2.

    if Capability.RATE_LIMITS_V2 in our_capabilities and Capability.RATE_LIMITS_V2 in peer_capabilities:
        # Use V2 rate limits
        if 2 in compose_rate_limits_cache:
            return compose_rate_limits_cache[2], aggregate_limit
        composed = copy.copy(rate_limits[1])
        composed.update(rate_limits[2])
        compose_rate_limits_cache[2] = composed
        return composed, aggregate_limit
    else:
        # Use V1 rate limits
        return rate_limits[1], aggregate_limit


# Each number in this dict corresponds to a specific version of rate limits (1, 2,  etc).
# Version 1 includes the original limits for chia software from versions 1.0 to 1.4.
rate_limits: dict[int, dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]]] = {
    1: {

Review comment (bug):
not sure it's wrong, but it seems a bit odd that `aggregate_limit.aggregate_limit` is `False`.  maybe this value is unused.

> [!NOTE]
> just formatting change here for clarity


```suggestion
aggregate_limit = RLSettings(
    aggregate_limit=False,
    frequency=1000,
    max_size=100 * 1024**3,
    max_total_size=100 * 1024**3,
)
```

but it looks like the `max_total_size` anyways was 100MiB not 100GiB as now?

https://github.com/Chia-Network/chia-blockchain/blob/cd792f5468e1661790660cfd1ad97c873ac9c25b/chia/server/rate_limit_numbers.py#L74
https://github.com/Chia-Network/chia-blockchain/blob/cd792f5468e1661790660cfd1ad97c873ac9c25b/chia/server/rate_limit_numbers.py#L186

maybe `.max_size` is unused.  though it seems like `0` would be a safer value for unused stuff.  more apt to point out any uses.

Code after:


# this class is used to configure the *rate* limit for a message type. The
# limits are counts and size per 60 seconds.
@dataclasses.dataclass(frozen=True)
class RLSettings:
    # if true, messages affect and are limited by the per connection aggregate limiter,
    # which affects messages across message types
    aggregate_limit: bool
    frequency: int  # Max request per time period (ie 1 min)
    max_size: int  # Max size of each request
    max_total_size: Optional[int] = None  # Max cumulative size of all requests in that period


# this class is used to indicate that a message type is not subject to a rate
# limit, but just a per-message size limit. This may be appropriate for response
# messages that are implicitly limited by their corresponding request message
# Unlimited message types are also not subject to the overall limit across all
# messages (just like messages in the "tx" category)
@dataclasses.dataclass(frozen=True)
class Unlimited:
    max_size: int  # Max size of each request


# for the aggregate limit, not all fields of RLSettings are used. Only "frequency" and "max_total_size"
aggregate_limit = RLSettings(
    aggregate_limit=False,
    frequency=1000,
    max_size=0,
    max_total_size=100 * 1024 * 1024,
)


def get_rate_limits_to_use(
    our_capabilities: list[Capability], peer_capabilities: list[Capability]
) -> tuple[dict[ProtocolMessageTypes, Union[RLSettings, Unlimited]], RLSettings]:
    # This will use the newest possible rate limits that both peers support. At this time there are only two
    # options, v1 and v2.

    if Capability.RATE_LIMITS_V2 in our_capabilities and Capability.RATE_LIMITS_V2 in peer_capabilities:
        # Use V2 rate limits
        if 2 in compose_rate_limits_cache:
            return compose_rate_limits_cache[2], aggregate_limit
        composed = {
            **rate_limits[1],
            **rate_limits[2],
        }
        compose_rate_limits_cache[2] = composed
        return composed, aggregate_limit
    else:
        # Use V1 rate limits