minor fixes
This commit is contained in:
parent
b273792ef0
commit
7f8f0c5823
@ -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.
|
||||||
|
@ -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, ¶ms, &mut substate, &mut [])
|
self.call(¶ms, &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, ¶ms, &mut substate)
|
self.create(¶ms, &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(¶ms.sender, ¶ms.address, ¶ms.value);
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
|
||||||
if e.engine.is_builtin(¶ms.address) {
|
if self.engine.is_builtin(¶ms.address) {
|
||||||
// if destination is builtin, try to execute it
|
// if destination is builtin, try to execute it
|
||||||
let cost = e.engine.cost_of_builtin(¶ms.address, ¶ms.data);
|
let cost = self.engine.cost_of_builtin(¶ms.address, ¶ms.data);
|
||||||
match cost <= params.gas {
|
match cost <= params.gas {
|
||||||
true => {
|
true => {
|
||||||
e.engine.execute_builtin(¶ms.address, ¶ms.data, output);
|
self.engine.execute_builtin(¶ms.address, ¶ms.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(¶ms, &mut ext)
|
evm.exec(¶ms, &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(¶ms.address);
|
self.state.new_contract(¶ms.address);
|
||||||
// then transfer value to it
|
// then transfer value to it
|
||||||
e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.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(¶ms, &mut ext)
|
evm.exec(¶ms, &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, ¶ms, &mut substate);
|
let res = ex.create(¶ms, &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, ¶ms, &mut substate, &mut []);
|
ex.call(¶ms, &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> {
|
||||||
|
@ -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>;
|
||||||
|
@ -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);
|
||||||
|
@ -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::*;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user