Skip to content
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

VM: Run transaction with custom EVM/Interpreter / API Discussion #636

Closed
s1na opened this issue Dec 19, 2019 · 5 comments
Closed

VM: Run transaction with custom EVM/Interpreter / API Discussion #636

s1na opened this issue Dec 19, 2019 · 5 comments

Comments

@s1na
Copy link
Contributor

s1na commented Dec 19, 2019

After the v4 refactoring, runTx instantiates the EVM class which in turn when executing a message instantiates the Interpreter class. One benefit of this would be to allow users to use their custom interpreter implementation. But it was decided to make this part of the API public only in a subsequent release.

@s1na
Copy link
Contributor Author

s1na commented Apr 28, 2020

Depending on what exactly we want to make part of the public API there are a few small issues that need to be worked around, due to how the code is structured now.

How it works now:

  • the EVM, Interpreter and EEI classes are all use-once-throw-away kinds of objects
  • runTx (+ runCall and runCode) instantiate an instance of EVM to execute a tx (or a call or code)
  • EVM in turn creates an EEI instance and an Interpreter instance, and passes EEI (which has the methods for contracts to interact with the environment) to Interpreter
  • These instances are all destroyed after the lifetime of that tx
  • EEI has a reference to EVM too for nested calls and creates

So the first question is which of these classes do we want to make public and configurable. Depends on use-cases, but my guess is probably Interpreter and EVM.

Second, since they're created for every tx and thrown away, probably a factory class should be passed in to the VM so that runTx can create new instances with it. (alternatively refactor how these classes work)

Let's say I want to test changing the logic of an opcode (or adding new ones, etc.). What I'll have to do then is:

  • I'd inherit Interpreter to FancyInterpreter and modify lookupOpInfo and getOpHandler to add my new opcode
  • Inherit the InterpreterFactory to FancyInterpreterFactory which creates FancyInterpreter` objects
  • Inherit EVM to FancyEVM which uses FancyInterpreterFactory to create FancyInterpreter instances instead
  • Same for EVMFactory to FancyEVMFactory, you know the drill
  • Pass in FancyEVMFactory either when creating the VM instance, or directly to the runTx method, which would use it to create FancyEVM objects

Alternatively, we could add something like a getNewEVMInstance to the VM that runTx would call each time. Then users would inherit VM and change that method. (probably not that different in complexity)

Hopefully someone can come up with a better approach

@holgerd77 holgerd77 changed the title Run transaction with custom EVM/Interpreter Run transaction with custom EVM/Interpreter / API Discussion Apr 29, 2020
@alcuadrado
Copy link
Member

I've been thinking about this lately, and I wonder what is the motivation for this change. The only one I remember is that @cgewecke wanted to override the behavior of log. Do you still have the need for this, Chris?

@cgewecke
Copy link
Contributor

cgewecke commented Apr 30, 2020

@alcuadrado I've been able to do everything I need to do using the step handler.

I had some ideas about conditionally making some opcodes free because I'm injecting Solidity statements into people's code to track execution which distorts the cost. But I think buidlerevm demonstrates that passive tracing is accurate and effective - ultimately that's how my use-case should be done.

@s1na
Copy link
Contributor Author

s1na commented May 18, 2020

Sorry for the late response. That's a valid question @alcuadrado and this decision shouldn't be taken lightly as it'll expose a large fraction of the internal api publicly.

The main reasons that come to my mind are to allow the usage of VM in similar (but slightly different) configurations: like testnets, similar chains (I think the Remix folks were asking about this, can't find the issue right now) where you want to modify the list of the opcodes/precompiles and their logic a bit. It's not clear to me what's the extent of changes we'll need to enable these use-cases.

Also when the VM is flexible it can be used as a tool for experimenters and researchers without needing to fork the code. A concrete example that I can bring which would help myself right now is for a code merklization experiment, where I need to manually supply the list of valid jumpdests to Interpreter when running txes.

Also related: #441

@holgerd77 holgerd77 changed the title Run transaction with custom EVM/Interpreter / API Discussion VM: Run transaction with custom EVM/Interpreter / API Discussion Jan 13, 2022
@holgerd77
Copy link
Member

Outdated and superseeded/partially solved by VM v6 breaking release EVM/VM refactor, will close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants