Skip to content
Merged
16 changes: 16 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,22 @@ impl Machine {
pub fn position(&self) -> &Result<usize, ExitReason> {
&self.position
}
/// Return a reference of the return range.
pub fn return_range(&self) -> &Range<U256> {
&self.return_range
}
/// Return a reference of the valids.
pub fn valids(&self) -> &Valids {
&self.valids
}
/// Return a reference of the return range.
pub fn code(&mut self) -> Vec<u8> {
self.code.to_vec()
}
/// Return a reference of the valids.
pub fn data(&self) -> Vec<u8> {
self.data.to_vec()
}

/// Create a new machine with given code and data.
pub fn new(
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/eval/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ pub fn call<H: Handler>(runtime: &mut Runtime, scheme: CallScheme, handler: &mut
gas,
scheme == CallScheme::StaticCall,
context,
out_offset,
out_len,
) {
Capture::Exit((reason, return_data)) => {
runtime.return_data_buffer = return_data;
Expand Down
2 changes: 2 additions & 0 deletions runtime/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ pub trait Handler {
target_gas: Option<u64>,
is_static: bool,
context: Context,
memory_offset: U256,
offset_len: U256,
) -> Capture<(ExitReason, Vec<u8>), Self::CallInterrupt>;
/// Feed in call feedback.
fn call_feedback(&mut self, _feedback: Self::CallFeedback) -> Result<(), ExitError> {
Expand Down
22 changes: 3 additions & 19 deletions runtime/src/interrupt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{ExitFatal, Handler, Runtime};
use crate::{Handler, Runtime};

/// Interrupt resolution.
pub enum Resolve<'a, 'config, H: Handler> {
Expand All @@ -9,6 +9,7 @@ pub enum Resolve<'a, 'config, H: Handler> {
}

/// Create interrupt resolution.
#[allow(dead_code)]
pub struct ResolveCreate<'a, 'config> {
runtime: &'a mut Runtime<'config>,
}
Expand All @@ -19,16 +20,8 @@ impl<'a, 'config> ResolveCreate<'a, 'config> {
}
}

impl<'a, 'config> Drop for ResolveCreate<'a, 'config> {
fn drop(&mut self) {
self.runtime.status = Err(ExitFatal::UnhandledInterrupt.into());
self.runtime
.machine
.exit(ExitFatal::UnhandledInterrupt.into());
}
}

/// Call interrupt resolution.
#[allow(dead_code)]
pub struct ResolveCall<'a, 'config> {
runtime: &'a mut Runtime<'config>,
}
Expand All @@ -38,12 +31,3 @@ impl<'a, 'config> ResolveCall<'a, 'config> {
Self { runtime }
}
}

impl<'a, 'config> Drop for ResolveCall<'a, 'config> {
fn drop(&mut self) {
self.runtime.status = Err(ExitFatal::UnhandledInterrupt.into());
self.runtime
.machine
.exit(ExitFatal::UnhandledInterrupt.into());
}
}
5 changes: 5 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ impl<'config> Runtime<'config> {
&mut self.machine
}

/// Get a reference to the return buffer
pub fn return_data_buffer(&mut self) -> &mut Vec<u8> {
&mut self.return_data_buffer
}

/// Get a reference to the execution context.
pub fn context(&self) -> &Context {
&self.context
Expand Down
44 changes: 33 additions & 11 deletions src/executor/stack/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,17 @@ pub trait StackState<'config>: Backend {
}
}

/// Data returned by a precompile on success.
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum PrecompileOutputType {
Exit(ExitSucceed),
Trap,
}

/// Data returned by a precompile on success.
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct PrecompileOutput {
pub exit_status: ExitSucceed,
pub output_type: PrecompileOutputType,
pub output: Vec<u8>,
}

Expand Down Expand Up @@ -921,11 +928,20 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet>
}) {
return match result {
Ok(PrecompileOutput {
exit_status,
output_type,
output,
}) => {
let _ = self.exit_substate(StackExitKind::Succeeded);
Capture::Exit((ExitReason::Succeed(exit_status), output))
if let PrecompileOutputType::Exit(exit_status) = output_type {
let _ = self.exit_substate(StackExitKind::Succeeded);
Capture::Exit((ExitReason::Succeed(exit_status), output))
} else {
Capture::Exit((
ExitReason::Error(ExitError::Other(std::borrow::Cow::Borrowed(
"Unsupported",
))),
output,
))
}
}
Err(PrecompileFailure::Error { exit_status }) => {
let _ = self.exit_substate(StackExitKind::Failed);
Expand Down Expand Up @@ -1134,6 +1150,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
target_gas: Option<u64>,
is_static: bool,
context: Context,
_memory_offset: U256,
_offset_len: U256,
) -> Capture<(ExitReason, Vec<u8>), Self::CallInterrupt> {
self.call_inner(
code_address,
Expand All @@ -1156,6 +1174,8 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
target_gas: Option<u64>,
is_static: bool,
context: Context,
_memory_offset: U256,
_offset_len: U256,
) -> Capture<(ExitReason, Vec<u8>), Self::CallInterrupt> {
let capture = self.call_inner(
code_address,
Expand Down Expand Up @@ -1215,13 +1235,13 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
}
}

struct StackExecutorHandle<'inner, 'config, 'precompiles, S, P> {
executor: &'inner mut StackExecutor<'config, 'precompiles, S, P>,
code_address: H160,
input: &'inner [u8],
gas_limit: Option<u64>,
context: &'inner Context,
is_static: bool,
pub struct StackExecutorHandle<'inner, 'config, 'precompiles, S, P> {
pub executor: &'inner mut StackExecutor<'config, 'precompiles, S, P>,
pub code_address: H160,
pub input: &'inner [u8],
pub gas_limit: Option<u64>,
pub context: &'inner Context,
pub is_static: bool,
}

impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> PrecompileHandle
Expand Down Expand Up @@ -1283,6 +1303,8 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr
gas_limit,
is_static,
context.clone(),
U256::default(),
U256::default(),
) {
Capture::Exit((s, v)) => (s, v),
Capture::Trap(_) => unreachable!("Trap is infaillible since StackExecutor is sync"),
Expand Down
37 changes: 37 additions & 0 deletions src/executor/stack/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ impl<'config> MemoryStackSubstate<'config> {
}
}

pub fn from_state(
metadata: StackSubstateMetadata<'config>,
logs: Vec<Log>,
accounts: BTreeMap<H160, MemoryStackAccount>,
storages: BTreeMap<(H160, H256), H256>,
deletes: BTreeSet<H160>,
) -> Self {
Self {
metadata,
parent: None,
logs,
accounts,
storages,
deletes,
}
}

pub fn logs(&self) -> &[Log] {
&self.logs
}
Expand All @@ -46,6 +63,18 @@ impl<'config> MemoryStackSubstate<'config> {
&mut self.logs
}

pub fn accounts(&self) -> &BTreeMap<H160, MemoryStackAccount> {
&self.accounts
}

pub fn storages(&self) -> &BTreeMap<(H160, H256), H256> {
&self.storages
}

pub fn deletes(&self) -> &BTreeSet<H160> {
&self.deletes
}

pub fn metadata(&self) -> &StackSubstateMetadata<'config> {
&self.metadata
}
Expand Down Expand Up @@ -555,6 +584,14 @@ impl<'backend, 'config, B: Backend> MemoryStackState<'backend, 'config, B> {
}
}

pub fn new_with_substate(substate: MemoryStackSubstate<'config>, backend: &'backend B) -> Self {
Self { backend, substate }
}

pub fn substate(&self) -> &MemoryStackSubstate {
&self.substate
}

/// Returns a mutable reference to an account given its address
pub fn account_mut(&mut self, address: H160) -> &mut MemoryStackAccount {
self.substate.account_mut(address, self.backend)
Expand Down
5 changes: 3 additions & 2 deletions src/executor/stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ mod executor;
mod memory;

pub use self::executor::{
Accessed, PrecompileFailure, PrecompileFn, PrecompileHandle, PrecompileOutput, PrecompileSet,
StackExecutor, StackExitKind, StackState, StackSubstateMetadata,
Accessed, PrecompileFailure, PrecompileFn, PrecompileHandle, PrecompileOutput,
PrecompileOutputType, PrecompileSet, StackExecutor, StackExecutorHandle, StackExitKind,
StackState, StackSubstateMetadata,
};

pub use self::memory::{MemoryStackAccount, MemoryStackState, MemoryStackSubstate};
Expand Down