minor fixes

This commit is contained in:
debris 2016-01-11 02:42:02 +01:00
parent b273792ef0
commit 7f8f0c5823
7 changed files with 46 additions and 34 deletions

View File

@ -1,7 +1,6 @@
//! Evm interface. //! Evm interface.
use util::uint::U256; use util::uint::U256;
use util::bytes::Bytes;
use evm::{EvmParams, Ext}; use evm::{EvmParams, Ext};
/// Evm errors. /// Evm errors.

View File

@ -1,3 +1,4 @@
//! Transaction Execution environment.
use std::collections::HashSet; use std::collections::HashSet;
use std::cmp; use std::cmp;
use std::ptr; use std::ptr;
@ -139,11 +140,11 @@ impl<'a> Executive<'a> {
} }
/// This funtion should be used to execute transaction. /// This funtion should be used to execute transaction.
pub fn transact(e: &mut Executive<'a>, t: &Transaction) -> ExecutionResult { pub fn transact(&mut self, t: &Transaction) -> ExecutionResult {
// TODO: validate transaction signature ?/ sender // TODO: validate transaction signature ?/ sender
let sender = t.sender(); let sender = t.sender();
let nonce = e.state.nonce(&sender); let nonce = self.state.nonce(&sender);
// validate transaction nonce // validate transaction nonce
if t.nonce != nonce { if t.nonce != nonce {
@ -151,16 +152,16 @@ impl<'a> Executive<'a> {
} }
// validate if transaction fits into given block // validate if transaction fits into given block
if e.info.gas_used + t.gas > e.info.gas_limit { if self.info.gas_used + t.gas > self.info.gas_limit {
return Err(ExecutionError::BlockGasLimitReached { return Err(ExecutionError::BlockGasLimitReached {
gas_limit: e.info.gas_limit, gas_limit: self.info.gas_limit,
gas_used: e.info.gas_used, gas_used: self.info.gas_used,
gas: t.gas gas: t.gas
}); });
} }
// TODO: we might need bigints here, or at least check overflows. // TODO: we might need bigints here, or at least check overflows.
let balance = e.state.balance(&sender); let balance = self.state.balance(&sender);
let gas_cost = t.gas * t.gas_price; let gas_cost = t.gas * t.gas_price;
let total_cost = t.value + gas_cost; let total_cost = t.value + gas_cost;
@ -170,7 +171,7 @@ impl<'a> Executive<'a> {
} }
// NOTE: there can be no invalid transactions from this point. // NOTE: there can be no invalid transactions from this point.
e.state.inc_nonce(&sender); self.state.inc_nonce(&sender);
let mut substate = Substate::new(); let mut substate = Substate::new();
let res = match t.kind() { let res = match t.kind() {
@ -185,7 +186,7 @@ impl<'a> Executive<'a> {
code: t.data.clone(), code: t.data.clone(),
data: vec![], data: vec![],
}; };
Executive::call(e, &params, &mut substate, &mut []) self.call(&params, &mut substate, &mut [])
}, },
TransactionKind::MessageCall => { TransactionKind::MessageCall => {
let params = EvmParams { let params = EvmParams {
@ -195,15 +196,15 @@ impl<'a> Executive<'a> {
gas: t.gas, gas: t.gas,
gas_price: t.gas_price, gas_price: t.gas_price,
value: t.value, value: t.value,
code: e.state.code(&t.to.clone().unwrap()).unwrap_or(vec![]), code: self.state.code(&t.to.clone().unwrap()).unwrap_or(vec![]),
data: t.data.clone(), data: t.data.clone(),
}; };
Executive::create(e, &params, &mut substate) self.create(&params, &mut substate)
} }
}; };
// finalize here! // finalize here!
e.finalize(substate, &sender, U256::zero(), U256::zero(), t.gas_price); self.finalize(substate, &sender, U256::zero(), U256::zero(), t.gas_price);
//res //res
Ok(Executed::new()) Ok(Executed::new())
} }
@ -212,23 +213,23 @@ impl<'a> Executive<'a> {
/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
/// Modifies the substate and the output. /// Modifies the substate and the output.
/// Returns either gas_left or `EvmError`. /// Returns either gas_left or `EvmError`.
fn call(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate, output: &mut [u8]) -> EvmResult { fn call(&mut self, params: &EvmParams, substate: &mut Substate, output: &mut [u8]) -> EvmResult {
// at first, transfer value to destination // at first, transfer value to destination
e.state.transfer_balance(&params.sender, &params.address, &params.value); self.state.transfer_balance(&params.sender, &params.address, &params.value);
if e.engine.is_builtin(&params.address) { if self.engine.is_builtin(&params.address) {
// if destination is builtin, try to execute it // if destination is builtin, try to execute it
let cost = e.engine.cost_of_builtin(&params.address, &params.data); let cost = self.engine.cost_of_builtin(&params.address, &params.data);
match cost <= params.gas { match cost <= params.gas {
true => { true => {
e.engine.execute_builtin(&params.address, &params.data, output); self.engine.execute_builtin(&params.address, &params.data, output);
Ok(params.gas - cost) Ok(params.gas - cost)
}, },
false => Err(EvmError::OutOfGas) false => Err(EvmError::OutOfGas)
} }
} else if params.code.len() > 0 { } else if params.code.len() > 0 {
// if destination is a contract, do normal message call // if destination is a contract, do normal message call
let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params, substate, OutputPolicy::Return(output)); let mut ext = Externalities::new(self.state, self.info, self.engine, self.depth, params, substate, OutputPolicy::Return(output));
let evm = VmFactory::create(); let evm = VmFactory::create();
evm.exec(&params, &mut ext) evm.exec(&params, &mut ext)
} else { } else {
@ -240,13 +241,13 @@ impl<'a> Executive<'a> {
/// Creates contract with given contract params. /// Creates contract with given contract params.
/// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides). /// NOTE. It does not finalize the transaction (doesn't do refunds, nor suicides).
/// Modifies the substate. /// Modifies the substate.
fn create(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> EvmResult { fn create(&mut self, params: &EvmParams, substate: &mut Substate) -> EvmResult {
// at first create new contract // at first create new contract
e.state.new_contract(&params.address); self.state.new_contract(&params.address);
// then transfer value to it // then transfer value to it
e.state.transfer_balance(&params.sender, &params.address, &params.value); self.state.transfer_balance(&params.sender, &params.address, &params.value);
let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params, substate, OutputPolicy::InitContract); let mut ext = Externalities::new(self.state, self.info, self.engine, self.depth, params, substate, OutputPolicy::InitContract);
let evm = VmFactory::create(); let evm = VmFactory::create();
evm.exec(&params, &mut ext) evm.exec(&params, &mut ext)
} }
@ -351,7 +352,7 @@ impl<'a> Ext for Externalities<'a> {
} }
} }
fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(Address, u64)> { fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(u64, Address)> {
// if balance is insufficient or we are to deep, return // if balance is insufficient or we are to deep, return
if self.state.balance(&self.params.address) < *endowment && self.depth >= 1024 { if self.state.balance(&self.params.address) < *endowment && self.depth >= 1024 {
return None return None
@ -376,14 +377,14 @@ impl<'a> Ext for Externalities<'a> {
{ {
let mut ex = Executive::from_parent(self); let mut ex = Executive::from_parent(self);
ex.state.inc_nonce(&address); ex.state.inc_nonce(&address);
let res = Executive::create(&mut ex, &params, &mut substate); let res = ex.create(&params, &mut substate);
} }
self.substate.accrue(substate); self.substate.accrue(substate);
Some((address, gas)) Some((gas, address))
} }
fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec<u8>, u64)> { fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> Option<u64> {
// TODO: validation of the call // TODO: validation of the call
println!("gas: {:?}", gas); println!("gas: {:?}", gas);
@ -431,12 +432,12 @@ impl<'a> Ext for Externalities<'a> {
{ {
let mut ex = Executive::from_parent(self); let mut ex = Executive::from_parent(self);
// TODO: take output into account // TODO: take output into account
Executive::call(&mut ex, &params, &mut substate, &mut []); ex.call(&params, &mut substate, output);
} }
self.substate.accrue(substate); self.substate.accrue(substate);
// TODO: replace call_gas with what's actually left // TODO: replace call_gas with what's actually left
Some((vec![], gas - gas_cost + call_gas)) Some(gas - gas_cost + call_gas)
} }
fn extcode(&self, address: &Address) -> Vec<u8> { fn extcode(&self, address: &Address) -> Vec<u8> {

View File

@ -20,14 +20,14 @@ pub trait Ext {
/// Creates new contract. /// Creates new contract.
/// If contract creation is successfull, /// If contract creation is successfull,
/// returns new contract address and gas left, /// return gas_left and contract address,
/// otherwise `None`. /// otherwise `None`.
fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(Address, u64)>; fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(u64, Address)>;
/// Message call. /// Message call.
/// If call is successfull, returns call output and gas left. /// If call is successfull, returns gas left.
/// otherwise `None`. /// otherwise `None`.
fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec<u8>, u64)>; fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> Option<u64>;
/// Returns code at given address /// Returns code at given address
fn extcode(&self, address: &Address) -> Vec<u8>; fn extcode(&self, address: &Address) -> Vec<u8>;

View File

@ -1,3 +1,4 @@
//! Just in time compiler execution environment.
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
@ -240,6 +241,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
return false; return false;
} }
// TODO: fix this!
let (mut output, gas) = opt.unwrap(); let (mut output, gas) = opt.unwrap();
out_beg = output.as_mut_ptr(); out_beg = output.as_mut_ptr();
mem::forget(output); mem::forget(output);

View File

@ -1,3 +1,4 @@
//! Transaction log entry.
use util::hash::*; use util::hash::*;
use util::bytes::*; use util::bytes::*;
use util::sha3::*; use util::sha3::*;

View File

@ -1,16 +1,26 @@
//! Evm input params.
use util::hash::*; use util::hash::*;
use util::uint::*; use util::uint::*;
use util::bytes::*; use util::bytes::*;
/// Evm input params. Everything else should be specified in Externalities.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct EvmParams { pub struct EvmParams {
/// Address of currently executed code.
pub address: Address, pub address: Address,
/// Sender of current part of the transaction.
pub sender: Address, pub sender: Address,
/// Transaction initiator.
pub origin: Address, pub origin: Address,
/// Gas paid up front for transaction execution
pub gas: U256, pub gas: U256,
/// Gas price.
pub gas_price: U256, pub gas_price: U256,
/// Transaction value.
pub value: U256, pub value: U256,
/// Code being executed.
pub code: Bytes, pub code: Bytes,
/// Input data.
pub data: Bytes pub data: Bytes
} }

View File

@ -2,8 +2,7 @@
use evm::Evm; use evm::Evm;
/// Vm factory. Creates appropriate Evm. /// Evm factory. Creates appropriate Evm.
/// TODO: SmartVm
pub struct VmFactory; pub struct VmFactory;
impl VmFactory { impl VmFactory {