NethermindEth / nethermind

A robust execution client for Ethereum node operators.
https://nethermind.io/nethermind-client
GNU General Public License v3.0
1.2k stars 409 forks source link

Handle deep EVM call stack using separate thread #1022

Open chfast opened 4 years ago

chfast commented 4 years ago

In relation to the discussion about supporting EVMC, I did small research on the issue of causing native stack overflow when handling EVM call stack naively.

What you can do is adapt a trick Aleth is using. At some EVM call depth height (e.g. 100, the number must be figured out experimentally) you offload execution to a dedicated thread. The thread will have new system stack space and you can specify the size of this stack in C# API. The execution is still sequential - we have to wait for the new thread to finish.

What would be even better is to use coroutines or filbers. These also need to create a separate stack space but this can be implement in a library without the need of creating a thread (this requires asking OS for help). However, to my knowledge C# do not support these out-of-the-box.

Aleth code: https://github.com/ethereum/aleth/blob/master/libethereum/ExtVM.cpp#L34-L57.

tkstanczak commented 4 years ago

hi @chfast not sure what you mean here? is that some issue with EVMC that would need to be handled specifically just to be able to support it?

we do not have a call stack per se - we have an iterative and not recursive approach

chfast commented 4 years ago

I don't think you will be able to support EVMC VMs with iterative approach.

This was mostly a brain dump. But this is a way to have recursive approach without exhausting system stack.

tkstanczak commented 4 years ago

Controversial. I would prefer the EVMC VM to be able to execute everything by just being injected an interface to state, executioin env and tx. Why does it need to impose some requirements on how the Nethermind VM is designed?

dceleda commented 1 year ago

@tkstanczak is it still valid?

kamilchodola commented 1 month ago

@tkstanczak Is it still something valid? Maybe we can check if this is something which can improve perf in any way? But feels like something tricky.

cc @benaadams

benaadams commented 1 month ago

Are many ways of doing this in .NET, can easily offload to seperate "fiber" by implementing the IThreadPoolWorkItem and queuing to threadpool with ThreadPool.UnsafeQueueUserWorkItem; however there very many other ways of doing this e.g. Task.Run etc

Not sure is anything actionable in this issue though?