Fix executive. Syncs to 62509.
This commit is contained in:
parent
24ed819c51
commit
2eead090d5
@ -8,10 +8,10 @@ use env_info::*;
|
|||||||
|
|
||||||
pub trait Ext {
|
pub trait Ext {
|
||||||
/// Returns a value for given key.
|
/// 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.
|
/// 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.
|
/// Returns address balance.
|
||||||
fn balance(&self, address: &Address) -> U256;
|
fn balance(&self, address: &Address) -> U256;
|
||||||
|
@ -175,14 +175,14 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
|
|||||||
fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) {
|
fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let i = H256::from_jit(&*index);
|
let i = H256::from_jit(&*index);
|
||||||
let o = self.ext.sload(&i);
|
let o = self.ext.storage_at(&i);
|
||||||
*out_value = o.into_jit();
|
*out_value = o.into_jit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) {
|
fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) {
|
||||||
unsafe {
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ impl FakeExt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Ext for 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()
|
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);
|
self.store.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +201,11 @@ impl<'a> Executive<'a> {
|
|||||||
let evm = Factory::create();
|
let evm = Factory::create();
|
||||||
evm.exec(¶ms, &mut ext)
|
evm.exec(¶ms, &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);
|
self.enact_result(&res, substate, unconfirmed_substate, backup);
|
||||||
|
// flush(format!("exec: new substate={:?}\n", substate));
|
||||||
res
|
res
|
||||||
} else {
|
} else {
|
||||||
// otherwise, nothing
|
// otherwise, nothing
|
||||||
@ -242,51 +246,43 @@ impl<'a> Executive<'a> {
|
|||||||
let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.refunds_count;
|
let sstore_refunds = U256::from(schedule.sstore_refund_gas) * substate.refunds_count;
|
||||||
// refunds from contract suicides
|
// refunds from contract suicides
|
||||||
let suicide_refunds = U256::from(schedule.suicide_refund_gas) * U256::from(substate.suicides.len());
|
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
|
// real ammount to refund
|
||||||
let gas_left = match &result { &Ok(x) => x, _ => x!(0) };
|
let gas_left_prerefund = 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 refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) / U256::from(2));
|
||||||
let refund_value = refund * t.gas_price;
|
let gas_left = gas_left_prerefund + refunded;
|
||||||
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);
|
|
||||||
|
|
||||||
// fees earned by author
|
let gas_used = t.gas - gas_left;
|
||||||
let fees = t.gas - refund;
|
let refund_value = gas_left * t.gas_price;
|
||||||
let fees_value = fees * t.gas_price;
|
let fees_value = gas_used * t.gas_price;
|
||||||
let author = &self.info.author;
|
|
||||||
self.state.add_balance(author, &fees_value);
|
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",
|
||||||
trace!("Compensating author: fees: {}, fees_value: {}, author: {}", fees, fees_value, author);
|
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
|
// perform suicides
|
||||||
for address in substate.suicides.iter() {
|
for address in substate.suicides.iter() {
|
||||||
trace!("Killing {}", address);
|
// trace!("Killing {}", address);
|
||||||
self.state.kill_account(address);
|
self.state.kill_account(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
let gas_used = t.gas - gas_left;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
||||||
Ok(_) => {
|
_ => {
|
||||||
Ok(Executed {
|
Ok(Executed {
|
||||||
gas: t.gas,
|
gas: t.gas,
|
||||||
gas_used: gas_used,
|
gas_used: gas_used,
|
||||||
refunded: refund,
|
refunded: refunded,
|
||||||
cumulative_gas_used: self.info.gas_used + gas_used,
|
cumulative_gas_used: self.info.gas_used + gas_used,
|
||||||
logs: substate.logs,
|
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![]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,15 +60,19 @@ impl<'a> Externalities<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Ext for 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)
|
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 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();
|
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)
|
self.state.set_storage(&self.params.address, key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use engine::Engine;
|
|||||||
use executive::Executive;
|
use executive::Executive;
|
||||||
use pod_account::*;
|
use pod_account::*;
|
||||||
use pod_state::*;
|
use pod_state::*;
|
||||||
|
use state_diff::*;
|
||||||
|
|
||||||
pub type ApplyResult = Result<Receipt, Error>;
|
pub type ApplyResult = Result<Receipt, Error>;
|
||||||
|
|
||||||
@ -106,11 +107,13 @@ impl State {
|
|||||||
|
|
||||||
/// Add `incr` to the balance of account `a`.
|
/// Add `incr` to the balance of account `a`.
|
||||||
pub fn add_balance(&mut self, a: &Address, incr: &U256) {
|
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)
|
self.require(a, false).add_balance(incr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract `decr` from the balance of account `a`.
|
/// Subtract `decr` from the balance of account `a`.
|
||||||
pub fn sub_balance(&mut self, a: &Address, decr: &U256) {
|
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)
|
self.require(a, false).sub_balance(decr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,8 +142,13 @@ impl State {
|
|||||||
/// Execute a given transaction.
|
/// Execute a given transaction.
|
||||||
/// This will change the state accordingly.
|
/// This will change the state accordingly.
|
||||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
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));
|
let e = try!(Executive::new(self, env_info, engine).transact(t));
|
||||||
//println!("Executed: {:?}", e);
|
//println!("Executed: {:?}", e);
|
||||||
|
|
||||||
|
flush(format!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod())));
|
||||||
self.commit();
|
self.commit();
|
||||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||||
debug!("Transaction receipt: {:?}", receipt);
|
debug!("Transaction receipt: {:?}", receipt);
|
||||||
|
@ -2,6 +2,7 @@ use common::*;
|
|||||||
|
|
||||||
/// State changes which should be applied in finalize,
|
/// State changes which should be applied in finalize,
|
||||||
/// after transaction is fully executed.
|
/// after transaction is fully executed.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Substate {
|
pub struct Substate {
|
||||||
/// Any accounts that have suicided.
|
/// Any accounts that have suicided.
|
||||||
pub suicides: HashSet<Address>,
|
pub suicides: HashSet<Address>,
|
||||||
|
@ -57,12 +57,12 @@ impl<'a> TestExt<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Ext for TestExt<'a> {
|
impl<'a> Ext for TestExt<'a> {
|
||||||
fn sload(&self, key: &H256) -> H256 {
|
fn storage_at(&self, key: &H256) -> H256 {
|
||||||
self.ext.sload(key)
|
self.ext.storage_at(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sstore(&mut self, key: H256, value: H256) {
|
fn set_storage_at(&mut self, key: H256, value: H256) {
|
||||||
self.ext.sstore(key, value)
|
self.ext.set_storage_at(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn balance(&self, address: &Address) -> U256 {
|
fn balance(&self, address: &Address) -> U256 {
|
||||||
|
Loading…
Reference in New Issue
Block a user