From a0bb1068afe1c2001f820464fbf37e2fbcd49d93 Mon Sep 17 00:00:00 2001 From: debris Date: Wed, 6 Jan 2016 17:53:59 +0100 Subject: [PATCH] evm env uses EnvInfo. blockhash function implementation --- rust-evmjit/src/lib.rs | 4 ++-- src/env_info.rs | 16 +++++++++++++- src/evm/env.rs | 19 ++++++++++++---- src/evm/jit.rs | 49 ++++++++++++++++++++++++++++++++---------- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/rust-evmjit/src/lib.rs b/rust-evmjit/src/lib.rs index a16b0dbe8..bbc377703 100644 --- a/rust-evmjit/src/lib.rs +++ b/rust-evmjit/src/lib.rs @@ -103,7 +103,7 @@ pub trait Env { fn sload(&self, index: *const JitI256, out_value: *mut JitI256); fn sstore(&mut self, index: *const JitI256, value: *const JitI256); fn balance(&self, address: *const JitH256, out_value: *mut JitI256); - fn blockhash(&self, number: *const JitI256, out_hash: *mut JitI256); + fn blockhash(&self, number: *const JitI256, out_hash: *mut JitH256); fn create(&mut self, io_gas: *mut u64, @@ -311,7 +311,7 @@ pub mod ffi { } #[no_mangle] - pub unsafe extern "C" fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) { + pub unsafe extern "C" fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitH256) { let env = &*env; env.blockhash(number, out_hash); } diff --git a/src/env_info.rs b/src/env_info.rs index dec8069ac..14750d18f 100644 --- a/src/env_info.rs +++ b/src/env_info.rs @@ -21,4 +21,18 @@ pub struct EnvInfo { pub last_hashes: LastHashes, /// The gas used. pub gas_used: U256, -} \ No newline at end of file +} + +impl EnvInfo { + pub fn new() -> EnvInfo { + EnvInfo { + number: U256::zero(), + author: Address::new(), + timestamp: U256::zero(), + difficulty: U256::zero(), + gas_limit: U256::zero(), + last_hashes: vec![], + gas_used: U256::zero() + } + } +} diff --git a/src/evm/env.rs b/src/evm/env.rs index b067154ba..24a21bcd2 100644 --- a/src/evm/env.rs +++ b/src/evm/env.rs @@ -5,6 +5,7 @@ use util::hash::*; use util::uint::*; use util::bytes::*; use state::*; +use env_info::*; use evm::LogEntry; struct SubState { @@ -34,15 +35,17 @@ impl SubState { /// extern crate ethcore; /// use util::hash::*; /// use ethcore::state::*; +/// use ethcore::env_info::*; /// use ethcore::evm::*; /// /// fn main() { /// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); /// let mut data = RuntimeData::new(); -/// let mut env = Env::new(State::new_temp(), address); +/// let mut env = Env::new(EnvInfo::new(), State::new_temp(), address); /// } /// ``` pub struct Env { + info: EnvInfo, state: State, address: Address, substate: SubState @@ -50,8 +53,9 @@ pub struct Env { impl Env { /// Creates new evm environment object with backing state. - pub fn new(state: State, address: Address) -> Env { + pub fn new(info: EnvInfo, state: State, address: Address) -> Env { Env { + info: info, state: state, address: address, substate: SubState::new() @@ -73,8 +77,15 @@ impl Env { self.state.balance(address) } - pub fn blockhash(&self, _number: &U256) -> H256 { - unimplemented!(); + /// Returns the hash of one of the 256 most recent complete blocks. + pub fn blockhash(&self, number: &U256) -> H256 { + match *number < self.info.number { + false => H256::from(&U256::zero()), + true => { + let index = self.info.number - *number - U256::one(); + self.info.last_hashes[index.low_u32() as usize].clone() + } + } } /// Creates new contract diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 44d9a386e..3055a84fe 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -75,6 +75,13 @@ impl IntoJit for H256 { } } +impl IntoJit for H256 { + fn into_jit(self) -> evmjit::H256 { + let i: evmjit::I256 = self.into_jit(); + From::from(i) + } +} + impl IntoJit for Address { fn into_jit(self) -> evmjit::I256 { H256::from(self).into_jit() @@ -141,7 +148,7 @@ impl<'a> evmjit::Env for EnvAdapter<'a> { } } - fn blockhash(&self, number: *const evmjit::I256, out_hash: *mut evmjit::I256) { + fn blockhash(&self, number: *const evmjit::I256, out_hash: *mut evmjit::H256) { unsafe { let n = U256::from_jit(&*number); let o = self.env.blockhash(&n); @@ -247,6 +254,7 @@ mod tests { use evm::jit::{FromJit, IntoJit}; use super::*; use state::*; + use env_info::*; #[test] fn test_to_and_from_u256() { @@ -263,7 +271,7 @@ mod tests { use std::str::FromStr; let h = H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap(); - let j = h.clone().into_jit(); + let j: ::evmjit::I256 = h.clone().into_jit(); let h2 = H256::from_jit(&j); assert_eq!(h, h2); } @@ -286,7 +294,7 @@ mod tests { data.gas = 0x174876e800; data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -302,7 +310,7 @@ mod tests { data.gas = 0x174876e800; data.code = "6000600020600055".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -318,7 +326,7 @@ mod tests { data.gas = 0x174876e800; data.code = "6005600420600055".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -335,7 +343,7 @@ mod tests { data.gas = 0x174876e800; data.code = "32600055".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -351,7 +359,7 @@ mod tests { data.gas = 0x174876e800; data.code = "33600055".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -385,7 +393,7 @@ mod tests { let mut state = State::new_temp(); state.set_code(&address, address_code); state.set_code(&caller, caller_code); - let mut env = Env::new(state, caller.clone()); + let mut env = Env::new(EnvInfo::new(), state, caller.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -404,7 +412,7 @@ mod tests { let mut state = State::new_temp(); state.add_balance(&address, &U256::from(0x10)); - let mut env = Env::new(state, address.clone()); + let mut env = Env::new(EnvInfo::new(), state, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let state = env.state(); @@ -420,7 +428,7 @@ mod tests { data.gas = 0x174876e800; data.code = "60006000a0".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let logs = env.logs(); @@ -448,7 +456,7 @@ mod tests { data.gas = 0x174876e800; data.code = "60ff6000533360206000a1".from_hex().unwrap(); - let mut env = Env::new(State::new_temp(), address.clone()); + let mut env = Env::new(EnvInfo::new(), State::new_temp(), address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); let logs = env.logs(); @@ -461,4 +469,23 @@ mod tests { assert_eq!(topic, &H256::from(address.clone())); assert_eq!(log.data(), &"ff00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); } + + #[test] + fn test_blockhash() { + let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); + let mut data = RuntimeData::new(); + data.address = address.clone(); + data.caller = address.clone(); + data.gas = 0x174876e800; + data.code = "600040600055".from_hex().unwrap(); + + let mut info = EnvInfo::new(); + info.number = U256::one(); + info.last_hashes.push(H256::from(address.clone())); + let mut env = Env::new(info, State::new_temp(), address.clone()); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); + let state = env.state(); + assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); + } }