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

Refactor call and create opcodes and frame call. #996

Open
rakita opened this issue Jan 21, 2024 · 3 comments
Open

Refactor call and create opcodes and frame call. #996

rakita opened this issue Jan 21, 2024 · 3 comments
Labels
feature New feature or lib ability refactor Refactor of the code

Comments

@rakita
Copy link
Member

rakita commented Jan 21, 2024

Please look into how this can be simplified and where the cutting point between the Instruction and sub call inside Evm should be, it is a little blurry now.

Try to consolidate both Create and calls into one structure, intention for both of them is to create a new call frame and execute some bytecode, pre and post interpreter logic is different but the flow is the same.

Try to make the frame stack more uniform, to be able to introduce new generic calls, this part is rigid in the Handler.

@rakita rakita added feature New feature or lib ability refactor Refactor of the code labels Jan 21, 2024
@rakita
Copy link
Member Author

rakita commented Jan 23, 2024

Brainstormed around this and what i concluded is that call stack needs to be generic over Frame.

For the frame to look something like this

trait Frame {
/// Runs the frame (Or interpreter) and returns the next frame if it is available.
 fn run(&mu self, host, instruction_table) -> Option<Frame>
/// Consumes child frame and inserts its outcome.
 fn insert_outcome(&mut self, child_frame);

Option<Frame> can be, Action::{SubFrame, Return, Error}. On return, the full frame is reinserted into the parent frame (or returned if it is last).

This means that Instructions for CALL/CREATE need to be set from revm create not from interpreter crate as instructions need to know how to execute precompile if needed or create frame.

This can be a pair of handlers that run_interpreter and insert_outcome.

With the implementation of EOF I hope this will become clearer as we would need this kind of abstraction.

@rakita
Copy link
Member Author

rakita commented Feb 12, 2024

Handler was partially refactored to have more simpler call flow.

To close this PR sub calls should be able to be generalised in trait and specified in the Handler.

@rakita
Copy link
Member Author

rakita commented Mar 4, 2024

We should override instructions from revm crate. This would allow us to do:

const fn host_instruction_table<'a, EXT, DB: Database>() -> InstructionTable<Evm<'a, EXT, DB>> {
    let mut table = make_instruction_table::<Evm<'a, EXT, DB>, BerlinSpec>();
    table[0xf0] = |interpreter, evm| {};
    table
}

This would make the current Interpreter::next_action be moved inside Host aka Evm, and would make Host trait not needed (maybe useful for testing).

The default impl of those host instructions should act as dummy (empty,fail) replacements in Interpreter.

For this PR we should have a trait Frame

trait Frame {
    /// New or init of the frame, it pops values from interpreter and created dyn Box over itself
    /// Called from instruction
    fn new(interpreter, evm) -> Option<Box<dyn Frame>>
    /// Run interpreter with all needed data.
    /// Called from main loop.
    fn run(evm, shared_memory,instruction_table) -> ReturnOrExtCall
    
    /// Called by child frame to returns the output 
    fn interpreter(&mut self) -> &mut Interpreter;
    /// That this Frame output and set it to parent Interpreter
    fn return_to_parent(self, parent: &mut Interpreter) 
}

/// Implemented for `Call` and `Crate` as those are the only ones that can be called from transaction.
trait FirstFrame {
    fn output(self) -> ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or lib ability refactor Refactor of the code
Projects
None yet
Development

No branches or pull requests

1 participant