evm env uses EnvInfo. blockhash function implementation

This commit is contained in:
debris 2016-01-06 17:53:59 +01:00
parent b447de9120
commit a0bb1068af
4 changed files with 70 additions and 18 deletions

View File

@ -103,7 +103,7 @@ pub trait Env {
fn sload(&self, index: *const JitI256, out_value: *mut JitI256); fn sload(&self, index: *const JitI256, out_value: *mut JitI256);
fn sstore(&mut self, index: *const JitI256, value: *const JitI256); fn sstore(&mut self, index: *const JitI256, value: *const JitI256);
fn balance(&self, address: *const JitH256, out_value: *mut 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, fn create(&mut self,
io_gas: *mut u64, io_gas: *mut u64,
@ -311,7 +311,7 @@ pub mod ffi {
} }
#[no_mangle] #[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; let env = &*env;
env.blockhash(number, out_hash); env.blockhash(number, out_hash);
} }

View File

@ -21,4 +21,18 @@ pub struct EnvInfo {
pub last_hashes: LastHashes, pub last_hashes: LastHashes,
/// The gas used. /// The gas used.
pub gas_used: U256, pub gas_used: U256,
} }
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()
}
}
}

View File

@ -5,6 +5,7 @@ use util::hash::*;
use util::uint::*; use util::uint::*;
use util::bytes::*; use util::bytes::*;
use state::*; use state::*;
use env_info::*;
use evm::LogEntry; use evm::LogEntry;
struct SubState { struct SubState {
@ -34,15 +35,17 @@ impl SubState {
/// extern crate ethcore; /// extern crate ethcore;
/// use util::hash::*; /// use util::hash::*;
/// use ethcore::state::*; /// use ethcore::state::*;
/// use ethcore::env_info::*;
/// use ethcore::evm::*; /// use ethcore::evm::*;
/// ///
/// fn main() { /// fn main() {
/// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); /// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
/// let mut data = RuntimeData::new(); /// 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 { pub struct Env {
info: EnvInfo,
state: State, state: State,
address: Address, address: Address,
substate: SubState substate: SubState
@ -50,8 +53,9 @@ pub struct Env {
impl Env { impl Env {
/// Creates new evm environment object with backing state. /// 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 { Env {
info: info,
state: state, state: state,
address: address, address: address,
substate: SubState::new() substate: SubState::new()
@ -73,8 +77,15 @@ impl Env {
self.state.balance(address) self.state.balance(address)
} }
pub fn blockhash(&self, _number: &U256) -> H256 { /// Returns the hash of one of the 256 most recent complete blocks.
unimplemented!(); 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 /// Creates new contract

View File

@ -75,6 +75,13 @@ impl IntoJit<evmjit::I256> for H256 {
} }
} }
impl IntoJit<evmjit::H256> for H256 {
fn into_jit(self) -> evmjit::H256 {
let i: evmjit::I256 = self.into_jit();
From::from(i)
}
}
impl IntoJit<evmjit::I256> for Address { impl IntoJit<evmjit::I256> for Address {
fn into_jit(self) -> evmjit::I256 { fn into_jit(self) -> evmjit::I256 {
H256::from(self).into_jit() 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 { unsafe {
let n = U256::from_jit(&*number); let n = U256::from_jit(&*number);
let o = self.env.blockhash(&n); let o = self.env.blockhash(&n);
@ -247,6 +254,7 @@ mod tests {
use evm::jit::{FromJit, IntoJit}; use evm::jit::{FromJit, IntoJit};
use super::*; use super::*;
use state::*; use state::*;
use env_info::*;
#[test] #[test]
fn test_to_and_from_u256() { fn test_to_and_from_u256() {
@ -263,7 +271,7 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
let h = H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap(); 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); let h2 = H256::from_jit(&j);
assert_eq!(h, h2); assert_eq!(h, h2);
} }
@ -286,7 +294,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -302,7 +310,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "6000600020600055".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -318,7 +326,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "6005600420600055".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -335,7 +343,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "32600055".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -351,7 +359,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "33600055".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -385,7 +393,7 @@ mod tests {
let mut state = State::new_temp(); let mut state = State::new_temp();
state.set_code(&address, address_code); state.set_code(&address, address_code);
state.set_code(&caller, caller_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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -404,7 +412,7 @@ mod tests {
let mut state = State::new_temp(); let mut state = State::new_temp();
state.add_balance(&address, &U256::from(0x10)); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state(); let state = env.state();
@ -420,7 +428,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "60006000a0".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let logs = env.logs(); let logs = env.logs();
@ -448,7 +456,7 @@ mod tests {
data.gas = 0x174876e800; data.gas = 0x174876e800;
data.code = "60ff6000533360206000a1".from_hex().unwrap(); 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; let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop); assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let logs = env.logs(); let logs = env.logs();
@ -461,4 +469,23 @@ mod tests {
assert_eq!(topic, &H256::from(address.clone())); assert_eq!(topic, &H256::from(address.clone()));
assert_eq!(log.data(), &"ff00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); 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()));
}
} }