-
Notifications
You must be signed in to change notification settings - Fork 34
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
Conversation
// Patches are reads as ConfigUpdates instead to handle omitted fields. | ||
func (c Config) MarshalJSON() ([]byte, error) { | ||
return json.Marshal(struct { | ||
MaxBlobSizeBytes uint64 `json:"MaxBlobSizeBytes"` |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
toeigenda
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.
There was a problem hiding this comment.
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.
verify/verifier.go
Outdated
@@ -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") |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh my bad - was referring to here: https://github.com/Layr-Labs/eigenda-proxy/blob/main/server/load_store.go#L138-L142
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
Not sure why the ci error started appearing just now...
…ter the refactor)
cb47d2b
to
4216b01
Compare
|
||
See [memconfig/config.go](./memconfig/config.go) for the configuration options. | ||
These can all be set via their respective flags or environment variables. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 @- | ||
``` |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 | ||
} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
Co-authored-by: ethenotethan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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