Fix executive. Syncs to 62509.

This commit is contained in:
Gav Wood 2016-01-15 18:56:28 +01:00
parent 24ed819c51
commit 2eead090d5
8 changed files with 49 additions and 40 deletions

View File

@ -8,10 +8,10 @@ use env_info::*;
pub trait Ext {
/// Returns a value for given key.
fn sload(&self, key: &H256) -> H256;
fn storage_at(&self, key: &H256) -> H256;
/// Stores a value for given key.
fn sstore(&mut self, key: H256, value: H256);
fn set_storage_at(&mut self, key: H256, value: H256);
/// Returns address balance.
fn balance(&self, address: &Address) -> U256;

View File

@ -175,14 +175,14 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) {
unsafe {
let i = H256::from_jit(&*index);
let o = self.ext.sload(&i);
let o = self.ext.storage_at(&i);
*out_value = o.into_jit();
}
}
fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) {
unsafe {
self.ext.sstore(H256::from_jit(&*index), H256::from_jit(&*value));
self.ext.set_storage_at(H256::from_jit(&*index), H256::from_jit(&*value));
}
}

View File

@ -26,11 +26,11 @@ impl FakeExt {
}
impl Ext for FakeExt {
fn sload(&self, key: &H256) -> H256 {
fn storage_at(&self, key: &H256) -> H256 {
self.store.get(key).unwrap_or(&H256::new()).clone()
}
fn sstore(&mut self, key: H256, value: H256) {
fn set_storage_at(&mut self, key: H256, value: H256) {
self.store.insert(key, value);
}

View File

@ -201,7 +201,11 @@ impl<'a> Executive<'a> {
let evm = Factory::create();
evm.exec(&params, &mut ext)
};
// flush(format!("exec: sstore-clears={}\n", unconfirmed_substate.refunds_count));
// flush(format!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate));
self.enact_result(&res, substate, unconfirmed_substate, backup);
// flush(format!("exec: new substate={:?}\n", substate));
res
} else {
// otherwise, nothing
@ -242,51 +246,43 @@ impl<'a> Executive<'a> {
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());
let refunds_bound = sstore_refunds + suicide_refunds;
// real ammount to refund
let gas_left = match &result { &Ok(x) => x, _ => x!(0) };
let refund = cmp::min(sstore_refunds + suicide_refunds, (t.gas - gas_left) / U256::from(2)) + gas_left;
let refund_value = refund * t.gas_price;
trace!("Refunding sender: sstore0s: {}, suicides: {}, gas_left: {}, refund: {}, refund_value: {}, sender: {}", sstore_refunds, suicide_refunds, gas_left, refund, refund_value, t.sender().unwrap());
self.state.add_balance(&t.sender().unwrap(), &refund_value);
let gas_left_prerefund = match &result { &Ok(x) => x, _ => x!(0) };
let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) / U256::from(2));
let gas_left = gas_left_prerefund + refunded;
// fees earned by author
let fees = t.gas - refund;
let fees_value = fees * t.gas_price;
let author = &self.info.author;
self.state.add_balance(author, &fees_value);
trace!("Compensating author: fees: {}, fees_value: {}, author: {}", fees, fees_value, author);
let gas_used = t.gas - gas_left;
let refund_value = gas_left * t.gas_price;
let fees_value = gas_used * t.gas_price;
flush(format!("exec::finalize: t.gas={}, sstore_refunds={}, suicide_refunds={}, refunds_bound={}, gas_left_prerefund={}, refunded={}, gas_left={}, gas_used={}, refund_value={}, fees_value={}\n",
t.gas, sstore_refunds, suicide_refunds, refunds_bound, gas_left_prerefund, refunded, gas_left, gas_used, refund_value, fees_value));
flush(format!("exec::finalize: Refunding sender={}\n", t.sender().unwrap()));
self.state.add_balance(&t.sender().unwrap(), &refund_value);
flush(format!("exec::finalize: Compensating author: fees_value: {}, author: {}", fees_value, &self.info.author));
self.state.add_balance(&self.info.author, &fees_value);
// perform suicides
for address in substate.suicides.iter() {
trace!("Killing {}", address);
// trace!("Killing {}", address);
self.state.kill_account(address);
}
let gas_used = t.gas - gas_left;
match result {
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
Ok(_) => {
_ => {
Ok(Executed {
gas: t.gas,
gas_used: gas_used,
refunded: refund,
refunded: refunded,
cumulative_gas_used: self.info.gas_used + gas_used,
logs: substate.logs,
contracts_created: substate.contracts_created
contracts_created: substate.contracts_created,
})
},
_err => {
Ok(Executed {
gas: t.gas,
gas_used: t.gas,
refunded: U256::zero(),
cumulative_gas_used: self.info.gas_used + t.gas,
logs: vec![],
contracts_created: vec![]
})
}
}
}

View File

@ -60,15 +60,19 @@ impl<'a> Externalities<'a> {
}
impl<'a> Ext for Externalities<'a> {
fn sload(&self, key: &H256) -> H256 {
fn storage_at(&self, key: &H256) -> H256 {
// flush(format!("ext: storage_at({}, {}) == {}\n", self.params.address, key, U256::from(self.state.storage_at(&self.params.address, key).as_slice())));
self.state.storage_at(&self.params.address, key)
}
fn sstore(&mut self, key: H256, value: H256) {
fn set_storage_at(&mut self, key: H256, value: H256) {
let old = self.state.storage_at(&self.params.address, &key);
// if SSTORE nonzero -> zero, increment refund count
if value == H256::new() && self.state.storage_at(&self.params.address, &key) != H256::new() {
if value.is_zero() && !old.is_zero() {
// flush(format!("ext: additional refund. {} -> {}\n", self.substate.refunds_count, self.substate.refunds_count + x!(1)));
self.substate.refunds_count = self.substate.refunds_count + U256::one();
}
// flush(format!("ext: set_storage_at({}, {}): {} -> {}\n", self.params.address, key, U256::from(old.as_slice()), U256::from(value.as_slice())));
self.state.set_storage(&self.params.address, key, value)
}

View File

@ -3,6 +3,7 @@ use engine::Engine;
use executive::Executive;
use pod_account::*;
use pod_state::*;
use state_diff::*;
pub type ApplyResult = Result<Receipt, Error>;
@ -106,11 +107,13 @@ impl State {
/// Add `incr` to the balance of account `a`.
pub fn add_balance(&mut self, a: &Address, incr: &U256) {
flush(format!("state: add_balance({}, {})\n", a, incr));
self.require(a, false).add_balance(incr)
}
/// Subtract `decr` from the balance of account `a`.
pub fn sub_balance(&mut self, a: &Address, decr: &U256) {
flush(format!("state: sub_balance({}, {})\n", a, decr));
self.require(a, false).sub_balance(decr)
}
@ -139,8 +142,13 @@ impl State {
/// Execute a given transaction.
/// This will change the state accordingly.
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
let old = self.to_pod();
let e = try!(Executive::new(self, env_info, engine).transact(t));
//println!("Executed: {:?}", e);
flush(format!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod())));
self.commit();
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
debug!("Transaction receipt: {:?}", receipt);

View File

@ -2,6 +2,7 @@ use common::*;
/// State changes which should be applied in finalize,
/// after transaction is fully executed.
#[derive(Debug)]
pub struct Substate {
/// Any accounts that have suicided.
pub suicides: HashSet<Address>,

View File

@ -57,12 +57,12 @@ impl<'a> TestExt<'a> {
}
impl<'a> Ext for TestExt<'a> {
fn sload(&self, key: &H256) -> H256 {
self.ext.sload(key)
fn storage_at(&self, key: &H256) -> H256 {
self.ext.storage_at(key)
}
fn sstore(&mut self, key: H256, value: H256) {
self.ext.sstore(key, value)
fn set_storage_at(&mut self, key: H256, value: H256) {
self.ext.set_storage_at(key, value)
}
fn balance(&self, address: &Address) -> U256 {