Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ratelimits: improve disabled limit handling #7803

Merged
merged 1 commit into from
Nov 13, 2024

Conversation

jsha
Copy link
Contributor

@jsha jsha commented Nov 12, 2024

In the FailedAuthorizations limits, there was code that intentionally ignored errLimitDisabled errors (errors.Is(err, errLimitDisabled)). However, that that resulted in those functions later using a returned limit value that was invalid (i.e. its zero value). That happened to trigger some later checks in validateTransaction. Specifically this check failed:

	if txn.cost > txn.limit.Burst {
    // error

When txt.limit.Burst is zero, this will always fail.

This problem doesn't really show up in prod, where all the limits are configured. But it showed up in tests, specifically TestPerformValidation_FailedValidationsTriggerPauseIdentifiersRatelimit, where the limits are constructed using a simplified config that leaves most of them disabled.

In this change, I tried to make handling of errLimitDisabled more consistent, and always return an allow-only transaction as early as possible instead of falling through the error condition.

Where that wasn't possible, I used a boolean to record whether the result of builder.getLimit() was valid before referencing any of its fields.

I also added some "shouldn't happen" errors to catch this problem earlier if it recurs.

I removed some "skip disabled limit" comments because those say "what the code does" (which the code also says), not "why the code does it".

Fixes the test failures in #7797.

In the FailedAuthorizations limits, there was code that intentionally ignored
errLimitDisabled errors (`errors.Is(err, errLimitDisabled)`). However,
that that resulted in those functions later using a returned `limit` value that
was invalid (i.e. its zero value). That happened to trigger some later checks in
validateTransaction. Specifically this check failed:

    	if txn.cost > txn.limit.Burst {
        // error

When txt.limit.Burst is zero, this will always fail.

This problem doesn't really show up in prod, where all the limits are
configured. But it showed up in tests, specifically
TestPerformValidation_FailedValidationsTriggerPauseIdentifiersRatelimit,
where the limits are constructed using a simplified config that leaves most of
them disabled.

In this change, I tried to make handling of errLimitDisabled more consistent,
and always return an allow-only transaction as early as possible instead of
falling through the error condition.

Where that wasn't possible, I used a boolean to record whether the result of
`builder.getLimit()` was valid before referencing any of its fields.

I also added some "shouldn't happen" errors to catch this problem earlier if it
recurs.
@beautifulentropy beautifulentropy merged commit 26a9910 into main Nov 13, 2024
12 checks passed
@beautifulentropy beautifulentropy deleted the transaction-consistent-returns-2 branch November 13, 2024 21:23
aarongable pushed a commit that referenced this pull request Nov 15, 2024
The zero value for `limit` is invalid, so returning `nil` in error cases
avoids silently returning invalid limits (and means that if code makes a
mistake and references an invalid limit it will be an obvious clear
stack trace).

This is more consistent, since the methods on `limit` use a pointer
receiver. Also, since `limit` is a fairly large object, this saves some
copying.

Related to #7803 and #7797.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants