evm env uses EnvInfo. blockhash function implementation
This commit is contained in:
parent
b447de9120
commit
a0bb1068af
@ -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);
|
||||
}
|
||||
|
@ -22,3 +22,17 @@ pub struct EnvInfo {
|
||||
/// The gas used.
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user