ethereum-optimism / ethereum-optimism/optimism

op-node: event-system customizability and plugins (ideas)

Open
#11,152 2 comments 1 reaction 0 assignees View on GitHub
A-op-node
Dominant language
Go
Stars
6.5k
Forks
4k
Avg merge
2d 15h
Merged PRs (30d)
145

Description

The op-node core consists of an event-broadcast system:
- Derivers: process events
- Emitters: output events

Through these events, the op-node sub-systems communicate tasks like block-processing, block-derivation from the DA, sequencing, etc.

The deriver/emitter is registered through `event.System`, which can execute these components either synchronously (current default), or in parallel (work in progress).

The components are "registered" with the system by name. This makes it possible to attribute metrics to each sub-system, and unregister as necessary.

### Plugins

This may be the beginning of a plugin-system; performing and triggering additional tasks by monitoring and emitting events is trivial.

The question is just how we load additional event derivers/emitters.

One option may be with Go plugins, to allow runtime customization. A Go plugin can be a DLL type file, auto-discovered in a directory by the op-node, and declare some global function as access-point to register new event-derivers/emitters from. Go plugins could be developed outside of the monorepo, import the monorepo as library, and utilize all the event/plugin types as necessary.

The drawback of Go plugins are the challenges with distribution; plugins are not packaged up with docker-images, or automatically platform-compatible. Still, runtime customization does open up a lot of extensibility, while keeping the core stack unified in the main repository. This may outweigh the distribution challenges. Besides, if the op-node docker image has a standard mounting point for a plugin-directory, and if a plugin is distributed as a bundle with each platform target, then it's relatively simple to work with.

Based on demand we may start a design doc in the [design-docs](https://github.com/ethereum-optimism/design-docs) repository to further expand on the idea.

### Event deriver/emitter composition

Not all plugins are additive however, some may want to *replace* certain subsets of functionality.
Unregistering/registering complete sub-systems might be too much, if only small things have to change.

To do so, we may want to change the event-deriver interface.

From:
```go
func (m *myDeriver) OnEvent(ev event.Event) bool {
switch ev.(type) {
case FooEvent: ...
case BarEvent: ...
}
}
```
To something more like:
```go
func (m *myDeriver) Setup(sys event.System) bool {
event.Register[FooEvent](sys, "foo-handling", func(ev FooEvent) {
... // replaces existing "foo-handling"
})
event.Register[BarEvent](sys, "bar-handling-my-extension", func(ev BarEvent) {
... // net-new event handler, to extend regular "bar-handling"
})
}
```
This would enable a finer level of detail, while also being more explicit about exactly *which* events a deriver needs to listen to. This way we can drop the "bool" return parameter, and possibly reduce event-processing overhead (no broadcast to derivers that just ignore the event).

### Permissions / metadata

If we are going with plugins, we may want the plugin to pre-declare which event types it will process and emit. And then enforce the input/output limitations to the plugin.

This way we can tell if a plugin is just listening to forkchoice-updates, or actually emitting engine-instructions.

Different event types could be declared, and categorized by *how they affect the op-node*, such that we can have standard-compatible extensions, as well as *consensus-breaking* extensions (for custom OP-Stack chains), or e.g. *plasma specific* extensions. This is similar to how apps in app-stores request system permission, and the user can trust that the app does not break their expectations. Or in OP-Stack context, that the plugin is compatible with a certain blockspace charter.

Contributor guide

Open the contributing guide

Research direction

Start by reading the op-node event.System implementation and the existing deriver/emitter registration described in the issue. Compare the proposed plugin loading, composition, and permission models, then look for a design decision or acceptance criteria; this issue has no concrete implementation target or defined done state.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.