ethereumjs-monorepo icon indicating copy to clipboard operation
ethereumjs-monorepo copied to clipboard

Monorepo: Replace Node.js EventEmitter

Open holgerd77 opened this issue 1 year ago • 6 comments
trafficstars

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.

holgerd77 avatar Sep 05 '24 14:09 holgerd77

//cc @wighawag

holgerd77 avatar Sep 05 '24 14:09 holgerd77

Some Remix usage of events here.

holgerd77 avatar Sep 05 '24 14:09 holgerd77

A few comments for posterity/discussion:

  1. The main use of the AsyncEventEmitter class is for pausing bytecode execution to be able to evaluate the state of the EVM at that specific point in execution (similarly to how our stepHook function runs where you can access the stack/memory/metadata for each opcode as its processed).
  2. I already did an initial exploration of eventemitter3 and it wouldn't work for us unless they have an async mode I'm not aware of. I took a first stab at trying to integrate it and use inside of our AsyncEventEmitter class and there were some edge cases in the API that were not 1-1 with the native EventEmitter class. See #3330

acolytec3 avatar Sep 05 '24 15:09 acolytec3

On 2.: Ok, but my idea would be that we would throw the AsyncEventEmitter class away?

holgerd77 avatar Sep 05 '24 16:09 holgerd77

Couldn't the eventemitter3 be wrapped/extended with additional functionality to mimic the nodejs native EventEmitter?

lukastanisic99 avatar Sep 06 '24 10:09 lukastanisic99

This is THE core issue still to be addressed for our breaking releases.

holgerd77 avatar Sep 20 '24 08:09 holgerd77

Closed by #3746

holgerd77 avatar Oct 31 '24 16:10 holgerd77