executive call
This commit is contained in:
parent
f7e9816d33
commit
3e90859d9d
@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
use std::cmp;
|
||||||
use util::hash::*;
|
use util::hash::*;
|
||||||
use util::uint::*;
|
use util::uint::*;
|
||||||
use util::rlp::*;
|
use util::rlp::*;
|
||||||
@ -26,7 +27,7 @@ pub struct Substate {
|
|||||||
/// Any logs.
|
/// Any logs.
|
||||||
logs: Vec<LogEntry>,
|
logs: Vec<LogEntry>,
|
||||||
/// Refund counter of SSTORE nonzero->zero.
|
/// Refund counter of SSTORE nonzero->zero.
|
||||||
refunds: U256,
|
refunds_count: U256,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Substate {
|
impl Substate {
|
||||||
@ -35,7 +36,7 @@ impl Substate {
|
|||||||
Substate {
|
Substate {
|
||||||
suicides: HashSet::new(),
|
suicides: HashSet::new(),
|
||||||
logs: vec![],
|
logs: vec![],
|
||||||
refunds: U256::zero(),
|
refunds_count: U256::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ impl Substate {
|
|||||||
fn accrue(&mut self, s: Substate) {
|
fn accrue(&mut self, s: Substate) {
|
||||||
self.suicides.extend(s.suicides.into_iter());
|
self.suicides.extend(s.suicides.into_iter());
|
||||||
self.logs.extend(s.logs.into_iter());
|
self.logs.extend(s.logs.into_iter());
|
||||||
self.refunds = self.refunds + s.refunds;
|
self.refunds_count = self.refunds_count + s.refunds_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ pub enum ExecutiveResult {
|
|||||||
InternalError
|
InternalError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Message-call/contract-creation executor; useful for executing transactions.
|
||||||
pub struct Executive<'a> {
|
pub struct Executive<'a> {
|
||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
@ -61,7 +63,6 @@ pub struct Executive<'a> {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Message-call/contract-creation executor; useful for executing transactions.
|
|
||||||
impl<'a> Executive<'a> {
|
impl<'a> Executive<'a> {
|
||||||
/// Creates new executive with depth equal 0.
|
/// Creates new executive with depth equal 0.
|
||||||
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self {
|
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self {
|
||||||
@ -126,21 +127,58 @@ impl<'a> Executive<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// finalize here!
|
// finalize here!
|
||||||
e.finalize(substate);
|
e.finalize(substate, U256::zero(), U256::zero());
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calls contract function with given contract params.
|
/// Calls contract function with given contract params.
|
||||||
/// *Note. It does not finalize the transaction (doesn't do refund).
|
/// *Note. It does not finalize the transaction (doesn't do refunds, nor suicides).
|
||||||
fn call(_e: &mut Executive<'a>, _p: &EvmParams, _s: &mut Substate) -> ExecutiveResult {
|
fn call(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> ExecutiveResult {
|
||||||
//let _ext = Externalities::from_executive(e, &p);
|
// at first, transfer value to destination
|
||||||
|
e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
|
||||||
|
// if destination is builtin, try to execute it, or quickly return
|
||||||
|
if e.engine.is_builtin(¶ms.address) {
|
||||||
|
return match e.engine.cost_of_builtin(¶ms.address, ¶ms.data) > params.gas {
|
||||||
|
true => ExecutiveResult::OutOfGas,
|
||||||
|
false => {
|
||||||
|
// TODO: substract gas for execution
|
||||||
|
let mut out = vec![];
|
||||||
|
e.engine.execute_builtin(¶ms.address, ¶ms.data, &mut out);
|
||||||
|
ExecutiveResult::Ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise do `normal` execution if destination is a contract
|
||||||
|
// TODO: is executing contract with no code different from not executing contract at all?
|
||||||
|
// if yes, there is a logic issue here. mk
|
||||||
|
if params.code.len() > 0 {
|
||||||
|
return match {
|
||||||
|
let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params, substate);
|
||||||
|
let evm = VmFactory::create();
|
||||||
|
evm.exec(¶ms, &mut ext)
|
||||||
|
} {
|
||||||
|
EvmResult::Stop => ExecutiveResult::Ok,
|
||||||
|
EvmResult::Return(_) => ExecutiveResult::Ok,
|
||||||
|
EvmResult::Suicide => {
|
||||||
|
substate.suicides.insert(params.address.clone());
|
||||||
|
ExecutiveResult::Ok
|
||||||
|
},
|
||||||
|
EvmResult::OutOfGas => ExecutiveResult::OutOfGas,
|
||||||
|
_err => ExecutiveResult::InternalError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ExecutiveResult::Ok
|
ExecutiveResult::Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates contract with given contract params.
|
/// Creates contract with given contract params.
|
||||||
/// *Note. It does not finalize the transaction (doesn't do refund).
|
/// *Note. It does not finalize the transaction (doesn't do refunds, nor suicides).
|
||||||
fn create(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> ExecutiveResult {
|
fn create(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> ExecutiveResult {
|
||||||
|
// at first create new contract
|
||||||
e.state.new_contract(¶ms.address);
|
e.state.new_contract(¶ms.address);
|
||||||
|
// then transfer value to it
|
||||||
e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
|
||||||
match {
|
match {
|
||||||
@ -156,6 +194,7 @@ impl<'a> Executive<'a> {
|
|||||||
ExecutiveResult::Ok
|
ExecutiveResult::Ok
|
||||||
},
|
},
|
||||||
EvmResult::Suicide => {
|
EvmResult::Suicide => {
|
||||||
|
substate.suicides.insert(params.address.clone());
|
||||||
ExecutiveResult::Ok
|
ExecutiveResult::Ok
|
||||||
},
|
},
|
||||||
EvmResult::OutOfGas => ExecutiveResult::OutOfGas,
|
EvmResult::OutOfGas => ExecutiveResult::OutOfGas,
|
||||||
@ -163,8 +202,19 @@ impl<'a> Executive<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the transaction (does refunds).
|
/// Finalizes the transaction (does refunds and suicides).
|
||||||
fn finalize(&self, _substate: Substate) {
|
fn finalize(&self, substate: Substate, gas: U256, gas_used: U256) {
|
||||||
|
let schedule = self.engine.evm_schedule(self.info);
|
||||||
|
|
||||||
|
// refunds from SSTORE nonzero -> zero
|
||||||
|
let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.refunds_count;
|
||||||
|
// refunds from contract suicides
|
||||||
|
let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len());
|
||||||
|
// real ammount to refund
|
||||||
|
let refund = cmp::min(sstore_refunds + suicide_refunds, (gas - gas_used) / U256::from(2));
|
||||||
|
|
||||||
|
// perform suicides
|
||||||
|
//self.state.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,12 +240,6 @@ impl<'a> Externalities<'a> {
|
|||||||
substate: substate
|
substate: substate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: figure out how to use this function
|
|
||||||
// so the lifetime checker is satisfied
|
|
||||||
//pub fn from_executive(e: &mut Executive<'a>, params: &EvmParams, substate: &mut Substate) -> Self {
|
|
||||||
//Externalities::new(e.state, e.info, e.engine, e.depth, params)
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Ext for Externalities<'a> {
|
impl<'a> Ext for Externalities<'a> {
|
||||||
@ -205,8 +249,8 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
|
|
||||||
fn sstore(&mut self, key: H256, value: H256) {
|
fn sstore(&mut self, key: H256, value: H256) {
|
||||||
if value == H256::new() && self.state.storage_at(&self.params.address, &key) != H256::new() {
|
if value == H256::new() && self.state.storage_at(&self.params.address, &key) != H256::new() {
|
||||||
//self.substate.refunds = self.substate.refunds + U256::from(self.engine.evm_schedule(self.info).sstore_refund_gas);
|
//self.substate.refunds_count = self.substate.refunds_count + U256::from(self.engine.evm_schedule(self.info).sstore_refund_gas);
|
||||||
self.substate.refunds = self.substate.refunds + U256::one();
|
self.substate.refunds_count = self.substate.refunds_count + U256::one();
|
||||||
}
|
}
|
||||||
self.state.set_storage(&self.params.address, key, value)
|
self.state.set_storage(&self.params.address, key, value)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user