From 22fc468d186ba9213112a71bc7bc744bbc1b51a5 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 23 Mar 2022 01:30:26 +0100 Subject: [PATCH 1/2] Extend precompile contract to execute subsequent EVM code call in context --- src/executor/stack/executor.rs | 47 ++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index 3d584d98..fd7ec291 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -214,11 +214,20 @@ pub trait StackState<'config>: Backend { /// Data returned by a precompile on success. #[derive(Debug, Eq, PartialEq, Clone)] -pub struct PrecompileOutput { - pub exit_status: ExitSucceed, - pub cost: u64, - pub output: Vec, - pub logs: Vec, +pub enum PrecompileOutput { + /// Exit the precompile execution and return an output. + Exit { + exit_status: ExitSucceed, + cost: u64, + output: Vec, + logs: Vec, + }, + /// Execute a set of EVM code in the context of the precompile. + Execute { + code: Vec, + input: Vec, + cost: u64, + }, } /// Data returned by a precompile in case of failure. @@ -855,12 +864,12 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> } } - if let Some(result) = + let (code, input) = if let Some(result) = self.precompile_set .execute(code_address, &input, Some(gas_limit), &context, is_static) { - return match result { - Ok(PrecompileOutput { + match result { + Ok(PrecompileOutput::Exit { exit_status, output, cost, @@ -882,11 +891,19 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> let _ = self.state.metadata_mut().gasometer.record_cost(cost); let _ = self.exit_substate(StackExitKind::Succeeded); - Capture::Exit((ExitReason::Succeed(exit_status), output)) + return Capture::Exit((ExitReason::Succeed(exit_status), output)) + } + Ok(PrecompileOutput::Execute { + input: precompile_input, + code: precompile_code, + cost, + }) => { + let _ = self.state.metadata_mut().gasometer.record_cost(cost); + (precompile_code, precompile_input) } Err(PrecompileFailure::Error { exit_status }) => { let _ = self.exit_substate(StackExitKind::Failed); - Capture::Exit((ExitReason::Error(exit_status), Vec::new())) + return Capture::Exit((ExitReason::Error(exit_status), Vec::new())) } Err(PrecompileFailure::Revert { exit_status, @@ -895,15 +912,17 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> }) => { let _ = self.state.metadata_mut().gasometer.record_cost(cost); let _ = self.exit_substate(StackExitKind::Reverted); - Capture::Exit((ExitReason::Revert(exit_status), output)) + return Capture::Exit((ExitReason::Revert(exit_status), output)) } Err(PrecompileFailure::Fatal { exit_status }) => { self.state.metadata_mut().gasometer.fail(); let _ = self.exit_substate(StackExitKind::Failed); - Capture::Exit((ExitReason::Fatal(exit_status), Vec::new())) + return Capture::Exit((ExitReason::Fatal(exit_status), Vec::new())) } - }; - } + } + } else { + (code, input) + }; let mut runtime = Runtime::new(Rc::new(code), Rc::new(input), context, self.config); From c64d5a9cb2aab8e7c4db8caa12f6bc1f8ca98603 Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Wed, 23 Mar 2022 01:41:33 +0100 Subject: [PATCH 2/2] Run cargo fmt --- src/executor/stack/executor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index fd7ec291..167dc8f2 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -891,7 +891,7 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> let _ = self.state.metadata_mut().gasometer.record_cost(cost); let _ = self.exit_substate(StackExitKind::Succeeded); - return Capture::Exit((ExitReason::Succeed(exit_status), output)) + return Capture::Exit((ExitReason::Succeed(exit_status), output)); } Ok(PrecompileOutput::Execute { input: precompile_input, @@ -903,7 +903,7 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> } Err(PrecompileFailure::Error { exit_status }) => { let _ = self.exit_substate(StackExitKind::Failed); - return Capture::Exit((ExitReason::Error(exit_status), Vec::new())) + return Capture::Exit((ExitReason::Error(exit_status), Vec::new())); } Err(PrecompileFailure::Revert { exit_status, @@ -912,12 +912,12 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> }) => { let _ = self.state.metadata_mut().gasometer.record_cost(cost); let _ = self.exit_substate(StackExitKind::Reverted); - return Capture::Exit((ExitReason::Revert(exit_status), output)) + return Capture::Exit((ExitReason::Revert(exit_status), output)); } Err(PrecompileFailure::Fatal { exit_status }) => { self.state.metadata_mut().gasometer.fail(); let _ = self.exit_substate(StackExitKind::Failed); - return Capture::Exit((ExitReason::Fatal(exit_status), Vec::new())) + return Capture::Exit((ExitReason::Fatal(exit_status), Vec::new())); } } } else {