ethereumjs-monorepo
ethereumjs-monorepo copied to clipboard
Monorepo: Replace Node.js EventEmitter
The Node.js native EventEmitter is the last Node.js primitive we still use in our libraries. This causes issues like #3439 and we should replace with a Node.js independent solution.
To summarize the current situation.
The basic EventEmitter from Node is used in:
- Client
- Common
- Devp2p
Then we have an AsyncEventEmitter integrated in Util which builds upon the Node.js event emitter and adds (correct me if I am wrong?) the functionality to "stop within events" (actually I am so so unsure what this thing actually adds, please someone clarify 😂 ).
This AsyncEventEmitter is then used in:
- Blockchain
- EVM
- VM
These event emitter usages should be removed by a - dependency-free - event emitter solution. I would find it most charming if we could eliminate this EventEmitter/AsyncEventEmitter separation and use one solution for both.
I found the following packages:
- https://github.com/sindresorhus/emittery (1.7K stars, no deps, JavaScript, "Simple and modern async event emitter")
- https://github.com/primus/eventemitter3 (3.3K stars, no deps, JavaScript, claims to be fast)
- https://github.com/EventEmitter2/EventEmitter2 (2.8K stars, no deps, JavaScript, somewhat rich feature description)
I did not found any meaningful TypeScript event emitter solutions, also, this list might not be complete.
EventEmitter2 might be a good choice having an explicit async mode (per flag), so it might suit an integrated approach well. But since I am understanding the requirements so badly I cannot help much atm with the choice otherwise TBH. 😬
@acolytec3 is already relatively deep in the topic and we already had several exchanges on that, so I guess it would be best if he takes this on.
//cc @wighawag
Some Remix usage of events here.
A few comments for posterity/discussion:
- The main use of the
AsyncEventEmitterclass is for pausing bytecode execution to be able to evaluate the state of the EVM at that specific point in execution (similarly to how ourstepHookfunction runs where you can access the stack/memory/metadata for each opcode as its processed). - I already did an initial exploration of
eventemitter3and it wouldn't work for us unless they have anasyncmode I'm not aware of. I took a first stab at trying to integrate it and use inside of ourAsyncEventEmitterclass and there were some edge cases in the API that were not 1-1 with the native EventEmitter class. See #3330
On 2.: Ok, but my idea would be that we would throw the AsyncEventEmitter class away?
Couldn't the eventemitter3 be wrapped/extended with additional functionality to mimic the nodejs native EventEmitter?
This is THE core issue still to be addressed for our breaking releases.
Closed by #3746