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

[proxyd]: Add block range rate limiting, and max block range to non-consensus mode #114

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

mdehoog
Copy link
Contributor

@mdehoog mdehoog commented Dec 25, 2024

Description

This PR implements two things:

  • the ability to limit the max block range, even if not in consensus mode
  • (opt-in, off by default) the ability to rate limit block range requests by block count

Tests

Added new tests.

Additional context

ethereum-optimism/optimism#6686 originally implemented the ability to limit block range requests. The initial implementation supported both consensus and non-consensus mode, however there was feedback on that PR that we already had latest block polling in consensus mode, and any block range limiting should be added to that.

We've since tried to use consensus mode, and even opened some PRs to help (e.g. ethereum-optimism/optimism#7275), but unfortunately our setup is not conducive to consensus mode.

@mdehoog mdehoog requested a review from a team as a code owner December 25, 2024 21:28
@mdehoog mdehoog requested a review from Inphi December 25, 2024 21:28
@jelias2
Copy link
Contributor

jelias2 commented Jan 10, 2025

Lmk if this is ready for review, typically would like to see CI passing as a prerequisite

@mdehoog mdehoog force-pushed the michael/block-range branch 4 times, most recently from 22d61a5 to 9891c81 Compare January 13, 2025 21:33
@mdehoog mdehoog force-pushed the michael/block-range branch from 9891c81 to d854e76 Compare January 13, 2025 21:42
// we are concerned about network error rates, so we record 1 request independently of how many are in the batch
b.networkRequestsSlidingWindow.Incr()
// (we don't count non-consensus polling towards error rates)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alternative to this is to disable the non-consensus poller in more tests by setting the nonconsensus_poller_interval negative... what do you think? To me it feels like we shouldn't be counting polling towards error rates, but I don't feel strongly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the sliding network requests sliding window should be counted. IRRC, its counted for the consensus_poller, I think it would be odd if it was counted for one strategy but not the other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally if the poll fails that helps proxyd determine if the backend is unstable at the moment, which is why I'd lean toward tracking the intermittent sliding window error as well

@mdehoog
Copy link
Contributor Author

mdehoog commented Jan 13, 2025

@jelias2 thank you 🙏

Apologies, I thought tests were passing when I marked this as ready for review, but I now realize it was only the check-updated-files check. All the tests have been fixed and CI is now passing.


func ExtractBlockRange(req *RPCReq, tracker BlockNumberTracker) *BlockRange {
switch req.Method {
case "eth_getLogs", "eth_newFilter":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eth_newFilter is only appended to a single backend, so it quite difficult to get the results from the requesting the filter through proxyd. We typically don't expose it on proxyd on our end. Curious your experience with it

A while ago there was a PR for similar functionality: #105, but I didn't see any interest in at the time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess eth_newFilter is used for overwriting the reqeust parameters, so it makes sense to keep it in here, but still I don't think that method works perfectly

@@ -182,6 +188,8 @@ type BackendGroupConfig struct {
ConsensusHALockPeriod TOMLDuration `toml:"consensus_ha_lock_period"`
ConsensusHARedis RedisConfig `toml:"consensus_ha_redis"`

NonconsensusPollerInterval TOMLDuration `toml:"nonconsensus_poller_interval"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I'm curious why the non-consensus poller is needed? If a backend was unable to serve a eth_getLogs in fallback mode, it would just request the next backend in the backend group? Whats the benefit of adding this component?

Copy link
Contributor

@jelias2 jelias2 Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The consensus poller allows re-writing of latest, safe, and finalized, I guess the major drawback would be if a eth_getLogs request goes a backend which doesn't have the non-consensus latest if would be missing the latest logs. Could you provide a bit more background on the behavior that this PR aims to fix and the expected results?

Comment on lines -125 to +121
return incr.Val()-1 < int64(r.max), nil
return incr.Val() <= int64(r.max), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious why removing the -1

p.lock.Lock()
defer p.lock.Unlock()

if *ptr < value || *ptr == math.MaxUint64 {
Copy link
Contributor

@jelias2 jelias2 Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the purpose of *ptr == math.MaxUnit64 in the conditional? Is this if the ptr is uninitialzed?

@jelias2
Copy link
Contributor

jelias2 commented Jan 15, 2025

Overall the blockrange rate limiting looks good if you want to open a second PR for that. For the max block range on non-consensus mode would like a bit more context.

Thanks for the contribution!

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.

2 participants