diff --git a/core/src/opcode.rs b/core/src/opcode.rs index 4736755c6..c4cbf82c4 100644 --- a/core/src/opcode.rs +++ b/core/src/opcode.rs @@ -273,7 +273,7 @@ impl Opcode { } impl fmt::Display for Opcode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //write!(f, "{}", "urgh...") let op = match self { &Opcode::STOP => "STOP", @@ -423,6 +423,5 @@ impl fmt::Display for Opcode { _ => "UNKNOWNOP", }; write!(f, "{}", op) - } + } } - diff --git a/src/backend/memory.rs b/src/backend/memory.rs index 7382a5e22..19b820e57 100644 --- a/src/backend/memory.rs +++ b/src/backend/memory.rs @@ -142,6 +142,10 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> { .unwrap_or_default() } + fn code_as_json(&self, address: H160) -> Vec { + self.code(address) + } + fn storage(&self, address: H160, index: H256) -> H256 { self.state .get(&address) @@ -152,6 +156,10 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> { fn original_storage(&self, address: H160, index: H256) -> Option { Some(self.storage(address, index)) } + + fn substate_as_json(&self, _address: H160, _vname: &str, _indices: &[String]) -> Vec { + Vec::new() + } } impl<'vicinity> ApplyBackend for MemoryBackend<'vicinity> { diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 1a503cbcc..9af7a16c7 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -79,10 +79,14 @@ pub trait Backend { fn basic(&self, address: H160) -> Basic; /// Get account code. fn code(&self, address: H160) -> Vec; - /// Get storage value of address at index. + /// Get account code formatted as json (if possible) + fn code_as_json(&self, address: H160) -> Vec; + /// Get storage value of address at inasex. fn storage(&self, address: H160, index: H256) -> H256; /// Get original storage value of address at index, if available. fn original_storage(&self, address: H160, index: H256) -> Option; + /// Get contract substate with given array of indices + fn substate_as_json(&self, address: H160, vname: &str, indices: &[String]) -> Vec; } /// EVM backend that can apply changes. diff --git a/src/executor/stack/executor.rs b/src/executor/stack/executor.rs index 888e08d35..1f989147e 100644 --- a/src/executor/stack/executor.rs +++ b/src/executor/stack/executor.rs @@ -285,20 +285,23 @@ pub trait PrecompileHandle { /// Record a log. fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError>; - /// Retreive the code address (what is the address of the precompile being called). + /// Retrieve the code address (what is the address of the precompile being called). fn code_address(&self) -> H160; - /// Retreive the input data the precompile is called with. + /// Retrieve the input data the precompile is called with. fn input(&self) -> &[u8]; - /// Retreive the context in which the precompile is executed. + /// Retrieve the context in which the precompile is executed. fn context(&self) -> &Context; /// Is the precompile call is done statically. fn is_static(&self) -> bool; - /// Retreive the gas limit of this call. + /// Retrieve the gas limit of this call. fn gas_limit(&self) -> Option; + + /// Retrieve backend + fn backend(&self) -> &dyn Backend; } /// A precompile result. @@ -335,8 +338,13 @@ impl PrecompileSet for () { /// * Is static /// /// In case of success returns the output and the cost. -pub type PrecompileFn = - fn(&[u8], Option, &Context, bool) -> Result<(PrecompileOutput, u64), PrecompileFailure>; +pub type PrecompileFn = fn( + &[u8], + Option, + &Context, + &dyn Backend, + bool, +) -> Result<(PrecompileOutput, u64), PrecompileFailure>; impl PrecompileSet for BTreeMap { fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { @@ -347,8 +355,9 @@ impl PrecompileSet for BTreeMap { let gas_limit = handle.gas_limit(); let context = handle.context(); let is_static = handle.is_static(); + let backend = handle.backend(); - match (*precompile)(input, gas_limit, context, is_static) { + match (*precompile)(input, gas_limit, context, backend, is_static) { Ok((output, cost)) => { handle.record_cost(cost)?; Ok(output) @@ -1330,17 +1339,17 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr Handler::log(self.executor, address, topics, data) } - /// Retreive the code address (what is the address of the precompile being called). + /// Retrieve the code address (what is the address of the precompile being called). fn code_address(&self) -> H160 { self.code_address } - /// Retreive the input data the precompile is called with. + /// Retrieve the input data the precompile is called with. fn input(&self) -> &[u8] { self.input } - /// Retreive the context in which the precompile is executed. + /// Retrieve the context in which the precompile is executed. fn context(&self) -> &Context { self.context } @@ -1350,8 +1359,12 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr self.is_static } - /// Retreive the gas limit of this call. + /// Retrieve the gas limit of this call. fn gas_limit(&self) -> Option { self.gas_limit } + + fn backend(&self) -> &dyn Backend { + &self.executor.state + } } diff --git a/src/executor/stack/memory.rs b/src/executor/stack/memory.rs index a1479279d..610268797 100644 --- a/src/executor/stack/memory.rs +++ b/src/executor/stack/memory.rs @@ -477,6 +477,10 @@ impl<'backend, 'config, B: Backend> Backend for MemoryStackState<'backend, 'conf .unwrap_or_else(|| self.backend.code(address)) } + fn code_as_json(&self, address: H160) -> Vec { + self.backend.code_as_json(address) + } + fn storage(&self, address: H160, key: H256) -> H256 { self.substate .known_storage(address, key) @@ -490,6 +494,10 @@ impl<'backend, 'config, B: Backend> Backend for MemoryStackState<'backend, 'conf self.backend.original_storage(address, key) } + + fn substate_as_json(&self, address: H160, vname: &str, indices: &[String]) -> Vec { + self.backend.substate_as_json(address, vname, indices) + } } impl<'backend, 'config, B: Backend> StackState<'config> for MemoryStackState<'backend, 'config, B> {