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

feat: add http routes and handlers to get/patch the memstore config #293

Merged
merged 13 commits into from
Feb 18, 2025

Conversation

samlaf
Copy link
Collaborator

@samlaf samlaf commented Feb 15, 2025

This is needed to create API-driven tests on the kurtosis devnet in our op fork.

See the new memstore README for details of the REST API.

Fixes Issue

Fixes #

Changes proposed

Screenshots (Optional)

Note to reviewers

@samlaf samlaf requested review from ethenotethan and litt3 February 15, 2025 05:12
// Patches are reads as ConfigUpdates instead to handle omitted fields.
func (c Config) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
MaxBlobSizeBytes uint64 `json:"MaxBlobSizeBytes"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not declare these tags in the above struct vs having a shadow declaration here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Originally I was using tags to change the name (using snake case), but I opted to just keep the names the same as the struct names. This struct is different from the struct above so would need its own tags, but you are right that they arent even needed (because default is to use same names), so I removed them: c2bc549

// It adds routes to the proxy's main router (to be served on same port as the main proxy routes):
// - GET /memstore/config: returns the current memstore configuration
// - PATCH /memstore/config: updates the memstore configuration
type HandlerHTTP struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we please put the handler outside of this package? Feels more appropriate to keep all the handlers bundled together

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I disagree, in my opinion every package should define its config/flags/metrics/routes, and then these can all be enabled/disabled, and the handlers can be added to the main router conditionally. This is also the way that op does it (look at rpc/api.go which defines the admin api for the batcher, op-node has a similar one, etc).

I could move them under memconfig/handlers/handlers.go if you prefer, but I felt this would just be unnecessary complexity for such a small package.

Also originally I had this memstore api behind a conditional flag, but I decided to just always enable it when memstore is enabled. Are you fine with that decision?

Copy link
Collaborator

Choose a reason for hiding this comment

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

my concern is we have a handlers.go defined in /server and now a handler construction in a file set that was initially just storage backend implementations - causing some complexity. imo we could either:

  • move the existing handlers from /server to eigenda backend. This wouldn't really work with V2 though since these method implementations are cross compatible between versions.
  • create a server/handlers package where we store all handler implementations - this would look smth like (handlers/proxy, handlers/memconfig). I'm very biased towards this approach since its how I've scaffolded go servers for the past few years haha

tangentially the abstract structuring of proxy could definitely use a reskin. E.g we use a load_store.go file for all dependency injection when we could have cleaner representations. In retrospect I wish this service wasn't pushed as a one week deliverable where we copy pasta'd OP Plasma's example server.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For 1. you prob meant move existing handlers to /store and not eigenda? The handlers in /server are the main handlers for the entire service, not only for eigenda backend.
I personally like this approach better, because I think the server should have a single responsibility of handling http traffic, and just being fed a router and using it dumbly. Every backend store or service understands its structure, so it should be the one creating handlers. Then the server only has to decide which router to bind these handlers to.

This structure makes a lot more sense to me. But what did you mean by "these method implementations are cross compatible between versions."?

But honestly I don't really anticipate having a ton more handlers defined going forward I think...? So prob would be fine to go with your approach.

@@ -61,10 +61,13 @@ func NewVerifier(cfg *Config, l logging.Logger) (*Verifier, error) {
var err error

if cfg.VerifyCerts {
log.Info("Certificate verification against Ethereum state enabled")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would prefer if we consolidated this message into a single Boolean field in the below service startup log

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean by this? What is "below service startup log"? Originally this log was in log_store.go but it felt more natural to me to move it here. Where would you prefer to have it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved the log around a bit (though still not sure this is what you wanted) and added a log line for kzg verifier: cf912ea

Now startup logs looks like:
image
image

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

hmm but that thing only shows "eigenda" and doesnt differentiate whether its memstore or actual eigenda

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

honestly I still think we should remove the option to disable cert verification when running eigenda. and for memstore perhaps we can disable the entire thing always (see your other msg). Perhaps we can do this in another PR though, since its a big change that deserves its own discussion potentially.

@samlaf samlaf requested a review from ethenotethan February 15, 2025 17:01
@samlaf samlaf force-pushed the feat--memstore-config-http-api branch from cb47d2b to 4216b01 Compare February 15, 2025 17:15
store/generated_key/memstore/README.md Outdated Show resolved Hide resolved
Comment on lines 12 to 14

See [memconfig/config.go](./memconfig/config.go) for the configuration options.
These can all be set via their respective flags or environment variables.
Copy link
Collaborator

Choose a reason for hiding this comment

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

can also run:

./bin/eigenda-proxy --help | grep memstore

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines +37 to +49
The PATCH request allows to patch the configuration. This allows only sending a subset of the configuration options. The other fields will be left intact.

```bash
$ curl -X PATCH http://localhost:3100/memstore/config -d '{"PutReturnsFailoverError": true}'
{"MaxBlobSizeBytes":16777216,"BlobExpiration":"25m0s","PutLatency":"0s","GetLatency":"0s","PutReturnsFailoverError":true}
```

One can of course still build a jq pipe to produce the same result (although still using PATCH instead of PUT since that is the only method available):
```bash
$ curl http://localhost:3100/memstore/config | \
jq '.PutLatency = "5s" | .GetLatency = "2s"' | \
curl -X PATCH http://localhost:3100/memstore/config -d @-
```
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we add a todo to codify a client for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines +66 to +86
func (sc *SafeConfig) LatencyPUTRoute() time.Duration {
sc.mu.RLock()
defer sc.mu.RUnlock()
return sc.config.PutLatency
}
func (sc *SafeConfig) SetLatencyPUTRoute(latency time.Duration) {
sc.mu.Lock()
defer sc.mu.Unlock()
sc.config.PutLatency = latency
}

func (sc *SafeConfig) LatencyGETRoute() time.Duration {
sc.mu.RLock()
defer sc.mu.RUnlock()
return sc.config.GetLatency
}
func (sc *SafeConfig) SetLatencyGETRoute(latency time.Duration) {
sc.mu.Lock()
defer sc.mu.Unlock()
sc.config.GetLatency = latency
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

why does latency have put/get accessor but other variables don't?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

put/get accessor?
They are all structured the same way: name of the variable is the getter, and SetXXX is the setter.

// We only use the verifier for kzgCommitment verification.
// MemStore generates random certs which can't be verified.
// TODO: we should probably refactor the Verifier to be able to only take in a BlobVerifier here.
verifier *verify.Verifier
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we even need this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

idk lol... wdyt? Wait is it even being used? The cert can't be fully random otherwise the kzgCommitment verification would fail right?

Copy link
Collaborator

@ethenotethan ethenotethan left a comment

Choose a reason for hiding this comment

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

LGTM

@samlaf samlaf merged commit daf39e2 into main Feb 18, 2025
10 checks passed
@samlaf samlaf deleted the feat--memstore-config-http-api branch February 18, 2025 20:53
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