From 2eead090d52b6e5abcff405fdb04fd2f50caa894 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 15 Jan 2016 18:56:28 +0100 Subject: [PATCH 1/5] Fix executive. Syncs to 62509. --- src/evm/ext.rs | 4 ++-- src/evm/jit.rs | 4 ++-- src/evm/tests.rs | 4 ++-- src/executive.rs | 50 +++++++++++++++++++----------------------- src/externalities.rs | 10 ++++++--- src/state.rs | 8 +++++++ src/substate.rs | 1 + src/tests/executive.rs | 8 +++---- 8 files changed, 49 insertions(+), 40 deletions(-) diff --git a/src/evm/ext.rs b/src/evm/ext.rs index ca06b5086..d74f847d7 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -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; diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 19a28de6f..122947d32 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -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)); } } diff --git a/src/evm/tests.rs b/src/evm/tests.rs index 3ed56bc39..f43881424 100644 --- a/src/evm/tests.rs +++ b/src/evm/tests.rs @@ -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); } diff --git a/src/executive.rs b/src/executive.rs index 8252b9221..bab431ed9 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -201,7 +201,11 @@ impl<'a> Executive<'a> { let evm = Factory::create(); 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); +// 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()); + 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; + + 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); - - // 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); + 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![] - }) - } } } diff --git a/src/externalities.rs b/src/externalities.rs index f5a72288a..28d27ffbc 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -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) } diff --git a/src/state.rs b/src/state.rs index 55a16b0ae..0c1a2e731 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,6 +3,7 @@ use engine::Engine; use executive::Executive; use pod_account::*; use pod_state::*; +use state_diff::*; pub type ApplyResult = Result; @@ -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); diff --git a/src/substate.rs b/src/substate.rs index f85427745..b227afacc 100644 --- a/src/substate.rs +++ b/src/substate.rs @@ -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
, diff --git a/src/tests/executive.rs b/src/tests/executive.rs index 3e0eae4b5..8b53e65bb 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -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 { From e876a04afbbb48abb074b9480e65d76b510f8bbe Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 15 Jan 2016 22:55:04 +0100 Subject: [PATCH 2/5] Bugs fixed for last_hashes. --- src/block.rs | 5 +++++ src/client.rs | 5 ++--- src/executive.rs | 10 ++++++---- src/externalities.rs | 20 ++++++++++++++++---- src/state.rs | 24 +++++++++++++++++------- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/block.rs b/src/block.rs index b93d52a60..35e56f19c 100644 --- a/src/block.rs +++ b/src/block.rs @@ -255,6 +255,11 @@ impl IsBlock for SealedBlock { /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header pub fn enact<'x, 'y>(block_bytes: &[u8], engine: &'x Engine, db: OverlayDB, parent: &Header, last_hashes: &'y LastHashes) -> Result, Error> { + { + let header = BlockView::new(block_bytes).header_view(); + let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce()); +// flush(format!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()))); + } let block = BlockView::new(block_bytes); let header = block.header_view(); let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author(), header.extra_data()); diff --git a/src/client.rs b/src/client.rs index 6a8acf6d3..ba0fe1a6e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -142,14 +142,13 @@ impl Client { }, }; // build last hashes - let mut last = self.chain.read().unwrap().best_block_hash(); let mut last_hashes = LastHashes::new(); last_hashes.resize(256, H256::new()); + last_hashes[0] = header.parent_hash.clone(); for i in 0..255 { - match self.chain.read().unwrap().block_details(&last) { + match self.chain.read().unwrap().block_details(&last_hashes[i]) { Some(details) => { last_hashes[i + 1] = details.parent.clone(); - last = details.parent.clone(); }, None => break, } diff --git a/src/executive.rs b/src/executive.rs index bab431ed9..867023528 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -196,6 +196,8 @@ impl<'a> Executive<'a> { // part of substate that may be reverted let mut unconfirmed_substate = Substate::new(); + info!("exec: call; env_info={:?}", self.info); + let res = { let mut ext = self.to_externalities(params, &mut unconfirmed_substate, OutputPolicy::Return(output)); let evm = Factory::create(); @@ -257,12 +259,12 @@ impl<'a> Executive<'a> { 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: 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())); +// flush(format!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, 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)); +// flush(format!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author)); self.state.add_balance(&self.info.author, &fees_value); // perform suicides diff --git a/src/externalities.rs b/src/externalities.rs index 28d27ffbc..9c9b08040 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -84,9 +84,14 @@ impl<'a> Ext for Externalities<'a> { match *number < U256::from(self.info.number) && number.low_u64() >= cmp::max(256, self.info.number) - 256 { true => { let index = self.info.number - number.low_u64() - 1; - self.info.last_hashes[index as usize].clone() + let r = self.info.last_hashes[index as usize].clone(); +// flush(format!("ext: blockhash({}) -> {} self.info.number={}\n", number, r, self.info.number)); + r + }, + false => { +// flush(format!("ext: blockhash({}) -> null self.info.number={}\n", number, self.info.number)); + H256::from(&U256::zero()) }, - false => H256::from(&U256::zero()), } } @@ -142,6 +147,8 @@ impl<'a> Ext for Externalities<'a> { call_gas = call_gas + U256::from(self.schedule.call_stipend); } +// flush(format!("Externalities::call(gas={}, call_gas={}, recv={}, value={}, data={}, code={})\n", gas, call_gas, receive_address, value, data.pretty(), code_address)); + if gas_cost > *gas { return Err(evm::Error::OutOfGas); } @@ -165,8 +172,13 @@ impl<'a> Ext for Externalities<'a> { data: Some(data.to_vec()), }; - let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth); - match ex.call(¶ms, self.substate, BytesRef::Fixed(output)) { + +// flush(format!("Externalities::call: BEFORE: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address))); +// flush(format!("Externalities::call: CALLING: params={:?}\n", params)); + let r = Executive::from_parent(self.state, self.info, self.engine, self.depth).call(¶ms, self.substate, BytesRef::Fixed(output)); +// flush(format!("Externalities::call: AFTER: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address))); + + match r { Ok(gas_left) => Ok((gas + gas_left, true)), _ => Ok((gas, false)) } diff --git a/src/state.rs b/src/state.rs index 0c1a2e731..d9ad0dfac 100644 --- a/src/state.rs +++ b/src/state.rs @@ -107,14 +107,16 @@ 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) +// let old = self.balance(a); + self.require(a, false).add_balance(incr); +// flush(format!("state: add_balance({}, {}): {} -> {}\n", a, incr, old, self.balance(a))); } /// 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) +// let old = self.balance(a); + self.require(a, false).sub_balance(decr); +// flush(format!("state: sub_balance({}, {}): {} -> {}\n", a, decr, old, self.balance(a))); } /// Subtracts `by` from the balance of `from` and adds it to that of `to`. @@ -148,7 +150,7 @@ impl State { 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()))); +// 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); @@ -227,8 +229,16 @@ impl State { /// Pull account `a` in our cache from the trie DB and return it. /// `require_code` requires that the code be cached, too. fn get(&self, a: &Address, require_code: bool) -> Ref> { - self.cache.borrow_mut().entry(a.clone()).or_insert_with(|| - SecTrieDB::new(&self.db, &self.root).get(&a).map(|rlp| Account::from_rlp(rlp))); + self.cache.borrow_mut().entry(a.clone()).or_insert_with(|| { + /*{ + let orlp = SecTrieDB::new(&self.db, &self.root).get(&a).map(|rlp| rlp.to_vec()); + if let Some(rlp) = orlp { + let acc = Account::from_rlp(&rlp); + flush(format!("State::get({}) -> {} (bal={})\n", a, rlp.pretty(), acc.balance())); + } + }*/ + SecTrieDB::new(&self.db, &self.root).get(&a).map(|rlp| Account::from_rlp(rlp)) + }); if require_code { if let Some(ref mut account) = self.cache.borrow_mut().get_mut(a).unwrap().as_mut() { account.cache_code(&self.db); From 4fde74c5e8d4e5d29152f52e40be8e28ebed41e1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 15 Jan 2016 23:32:17 +0100 Subject: [PATCH 3/5] Fix for sync. --- src/block.rs | 16 +++++++++++++++- src/ethereum/ethash.rs | 2 ++ src/executive.rs | 2 -- src/header.rs | 6 ++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/block.rs b/src/block.rs index 35e56f19c..beb35fc41 100644 --- a/src/block.rs +++ b/src/block.rs @@ -126,6 +126,15 @@ impl<'x, 'y> OpenBlock<'x, 'y> { /// Alter the timestamp of the block. pub fn set_timestamp(&mut self, timestamp: u64) { self.block.header.set_timestamp(timestamp); } + /// Alter the difficulty for the block. + pub fn set_difficulty(&mut self, a: U256) { self.block.header.set_difficulty(a); } + + /// Alter the gas limit for the block. + pub fn set_gas_limit(&mut self, a: U256) { self.block.header.set_gas_limit(a); } + + /// Alter the gas limit for the block. + pub fn set_gas_used(&mut self, a: U256) { self.block.header.set_gas_used(a); } + /// Alter the extra_data for the block. pub fn set_extra_data(&mut self, extra_data: Bytes) -> Result<(), BlockError> { if extra_data.len() > self.engine.maximum_extra_data_size() { @@ -158,7 +167,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> { author: self.block.header.author.clone(), timestamp: self.block.header.timestamp, difficulty: self.block.header.difficulty.clone(), - last_hashes: self.last_hashes.clone(), + last_hashes: self.last_hashes.clone(), // TODO: should be a reference. gas_used: self.block.archive.last().map(|t| t.receipt.gas_used).unwrap_or(U256::from(0)), gas_limit: self.block.header.gas_limit.clone(), } @@ -169,6 +178,7 @@ impl<'x, 'y> OpenBlock<'x, 'y> { /// If valid, it will be executed, and archived together with the receipt. pub fn push_transaction(&mut self, t: Transaction, h: Option) -> Result<&Receipt, Error> { let env_info = self.env_info(); +// info!("env_info says gas_used={}", env_info.gas_used); match self.block.state.apply(&env_info, self.engine, &t) { Ok(receipt) => { self.block.archive_set.insert(h.unwrap_or_else(||t.hash())); @@ -260,10 +270,14 @@ pub fn enact<'x, 'y>(block_bytes: &[u8], engine: &'x Engine, db: OverlayDB, pare let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce()); // flush(format!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()))); } + let block = BlockView::new(block_bytes); let header = block.header_view(); let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author(), header.extra_data()); + b.set_difficulty(header.difficulty()); + b.set_gas_limit(header.gas_limit()); b.set_timestamp(header.timestamp()); +// info!("enact: Enacting #{}. env_info={:?}", header.number(), b.env_info()); for t in block.transactions().into_iter() { try!(b.push_transaction(t, None)); } for u in block.uncles().into_iter() { try!(b.push_uncle(u)); } Ok(b.close()) diff --git a/src/ethereum/ethash.rs b/src/ethereum/ethash.rs index 69fb2691f..989ab8cd9 100644 --- a/src/ethereum/ethash.rs +++ b/src/ethereum/ethash.rs @@ -43,6 +43,8 @@ impl Engine for Ethash { max(gas_floor_target, gas_limit - gas_limit / bound_divisor + x!(1) + (header.gas_used * x!(6) / x!(5)) / bound_divisor) } }; + +// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit); } /// Apply the block reward on finalisation of the block. diff --git a/src/executive.rs b/src/executive.rs index 867023528..9d2562029 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -196,8 +196,6 @@ impl<'a> Executive<'a> { // part of substate that may be reverted let mut unconfirmed_substate = Substate::new(); - info!("exec: call; env_info={:?}", self.info); - let res = { let mut ext = self.to_externalities(params, &mut unconfirmed_substate, OutputPolicy::Return(output)); let evm = Factory::create(); diff --git a/src/header.rs b/src/header.rs index 45190332d..9226137b3 100644 --- a/src/header.rs +++ b/src/header.rs @@ -67,7 +67,9 @@ impl Header { pub fn state_root(&self) -> &H256 { &self.state_root } pub fn receipts_root(&self) -> &H256 { &self.receipts_root } + pub fn gas_limit(&self) -> &U256 { &self.gas_limit } + pub fn difficulty(&self) -> &U256 { &self.difficulty } pub fn seal(&self) -> &Vec { &self.seal } // TODO: seal_at, set_seal_at &c. @@ -79,6 +81,10 @@ impl Header { pub fn set_extra_data(&mut self, a: Bytes) { if a != self.extra_data { self.extra_data = a; self.note_dirty(); } } + pub fn set_gas_used(&mut self, a: U256) { self.gas_used = a; self.note_dirty(); } + pub fn set_gas_limit(&mut self, a: U256) { self.gas_limit = a; self.note_dirty(); } + + pub fn set_difficulty(&mut self, a: U256) { self.difficulty = a; self.note_dirty(); } pub fn set_seal(&mut self, a: Vec) { self.seal = a; self.note_dirty(); } /// Get the hash of this header (sha3 of the RLP). From 2f14b755f10ae0fed5da48eebd3a133ec4f9942a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 16 Jan 2016 01:44:07 +0100 Subject: [PATCH 4/5] Make stuff work. --- src/account.rs | 1 - src/executive.rs | 1 + src/externalities.rs | 7 +++++-- src/state.rs | 2 +- src/verification.rs | 10 +++++----- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/account.rs b/src/account.rs index 597d49053..8c36c7cbd 100644 --- a/src/account.rs +++ b/src/account.rs @@ -205,7 +205,6 @@ impl Account { match (self.code_hash.is_none(), self.code_cache.is_empty()) { (true, true) => self.code_hash = Some(SHA3_EMPTY), (true, false) => { - println!("Writing into DB {:?}", self.code_cache); self.code_hash = Some(db.insert(&self.code_cache)); }, (false, _) => {}, diff --git a/src/executive.rs b/src/executive.rs index 9d2562029..01bed3fd7 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -171,6 +171,7 @@ impl<'a> Executive<'a> { // at first, transfer value to destination self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); + debug!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); if self.engine.is_builtin(¶ms.code_address) { // if destination is builtin, try to execute it diff --git a/src/externalities.rs b/src/externalities.rs index 9c9b08040..654a27a05 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -133,6 +133,7 @@ impl<'a> Ext for Externalities<'a> { data: &[u8], code_address: &Address, output: &mut [u8]) -> Result<(U256, bool), evm::Error> { + let mut gas_cost = *call_gas; let mut call_gas = *call_gas; @@ -147,9 +148,10 @@ impl<'a> Ext for Externalities<'a> { call_gas = call_gas + U256::from(self.schedule.call_stipend); } -// flush(format!("Externalities::call(gas={}, call_gas={}, recv={}, value={}, data={}, code={})\n", gas, call_gas, receive_address, value, data.pretty(), code_address)); + debug!("Externalities::call(gas={}, call_gas={}, recv={}, value={}, data={}, code={})\n", gas, call_gas, receive_address, value, data.pretty(), code_address); if gas_cost > *gas { + debug!("Externalities::call: OutOfGas gas_cost={}, gas={}", gas_cost, gas); return Err(evm::Error::OutOfGas); } @@ -157,7 +159,8 @@ impl<'a> Ext for Externalities<'a> { // if balance is insufficient or we are too deep, return if self.state.balance(&self.params.address) < *value || self.depth >= self.schedule.max_depth { - return Ok((gas + call_gas, true)); + debug!("Externalities::call: OutOfCash bal({})={}, value={}", self.params.address, self.state.balance(&self.params.address), value); + return Ok((gas + call_gas, false)); } let params = ActionParams { diff --git a/src/state.rs b/src/state.rs index d9ad0dfac..98d1eacc3 100644 --- a/src/state.rs +++ b/src/state.rs @@ -150,7 +150,7 @@ impl State { 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()))); + debug!("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); diff --git a/src/verification.rs b/src/verification.rs index 4383f5a4a..bb7b912aa 100644 --- a/src/verification.rs +++ b/src/verification.rs @@ -115,18 +115,18 @@ pub fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, b /// Phase 4 verification. Check block information against transaction enactment results, pub fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> { - if expected.state_root != got.state_root { - return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root.clone(), found: got.state_root.clone() }))) + if expected.gas_used != got.gas_used { + return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used, found: got.gas_used }))) } if expected.receipts_root != got.receipts_root { return Err(From::from(BlockError::InvalidReceiptsStateRoot(Mismatch { expected: expected.receipts_root.clone(), found: got.receipts_root.clone() }))) } + if expected.state_root != got.state_root { + return Err(From::from(BlockError::InvalidStateRoot(Mismatch { expected: expected.state_root.clone(), found: got.state_root.clone() }))) + } if expected.log_bloom != got.log_bloom { return Err(From::from(BlockError::InvalidLogBloom(Mismatch { expected: expected.log_bloom.clone(), found: got.log_bloom.clone() }))) } - if expected.gas_used != got.gas_used { - return Err(From::from(BlockError::InvalidGasUsed(Mismatch { expected: expected.gas_used, found: got.gas_used }))) - } Ok(()) } From 5a2fab8b644ad6e35d82f40d5958c4ba56197472 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 16 Jan 2016 01:48:38 +0100 Subject: [PATCH 5/5] Clean up logging. --- src/block.rs | 2 +- src/executive.rs | 16 ++++++++-------- src/externalities.rs | 16 ++++++++-------- src/state.rs | 15 ++++----------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/block.rs b/src/block.rs index beb35fc41..d149d6132 100644 --- a/src/block.rs +++ b/src/block.rs @@ -268,7 +268,7 @@ pub fn enact<'x, 'y>(block_bytes: &[u8], engine: &'x Engine, db: OverlayDB, pare { let header = BlockView::new(block_bytes).header_view(); let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce()); -// flush(format!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()))); + trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author())); } let block = BlockView::new(block_bytes); diff --git a/src/executive.rs b/src/executive.rs index 01bed3fd7..9c3a545a5 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -203,10 +203,10 @@ impl<'a> Executive<'a> { 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)); + trace!("exec: sstore-clears={}\n", unconfirmed_substate.refunds_count); + trace!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate); self.enact_result(&res, substate, unconfirmed_substate, backup); -// flush(format!("exec: new substate={:?}\n", substate)); + trace!("exec: new substate={:?}\n", substate); res } else { // otherwise, nothing @@ -258,17 +258,17 @@ impl<'a> Executive<'a> { 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)); + trace!("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 refund_value={}, sender={}\n", refund_value, t.sender().unwrap())); + trace!("exec::finalize: Refunding refund_value={}, sender={}\n", refund_value, t.sender().unwrap()); self.state.add_balance(&t.sender().unwrap(), &refund_value); -// flush(format!("exec::finalize: Compensating author: fees_value={}, author={}\n", fees_value, &self.info.author)); + trace!("exec::finalize: Compensating author: fees_value={}, author={}\n", 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); } diff --git a/src/externalities.rs b/src/externalities.rs index 654a27a05..8c75a71f4 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -61,7 +61,7 @@ impl<'a> Externalities<'a> { impl<'a> Ext for Externalities<'a> { 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()))); + trace!("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) } @@ -69,10 +69,10 @@ impl<'a> Ext for Externalities<'a> { let old = self.state.storage_at(&self.params.address, &key); // if SSTORE nonzero -> zero, increment refund count if value.is_zero() && !old.is_zero() { -// flush(format!("ext: additional refund. {} -> {}\n", self.substate.refunds_count, self.substate.refunds_count + x!(1))); + trace!("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()))); + trace!("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) } @@ -85,11 +85,11 @@ impl<'a> Ext for Externalities<'a> { true => { let index = self.info.number - number.low_u64() - 1; let r = self.info.last_hashes[index as usize].clone(); -// flush(format!("ext: blockhash({}) -> {} self.info.number={}\n", number, r, self.info.number)); + trace!("ext: blockhash({}) -> {} self.info.number={}\n", number, r, self.info.number); r }, false => { -// flush(format!("ext: blockhash({}) -> null self.info.number={}\n", number, self.info.number)); + trace!("ext: blockhash({}) -> null self.info.number={}\n", number, self.info.number); H256::from(&U256::zero()) }, } @@ -176,10 +176,10 @@ impl<'a> Ext for Externalities<'a> { }; -// flush(format!("Externalities::call: BEFORE: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address))); -// flush(format!("Externalities::call: CALLING: params={:?}\n", params)); + trace!("Externalities::call: BEFORE: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address)); + trace!("Externalities::call: CALLING: params={:?}\n", params); let r = Executive::from_parent(self.state, self.info, self.engine, self.depth).call(¶ms, self.substate, BytesRef::Fixed(output)); -// flush(format!("Externalities::call: AFTER: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address))); + trace!("Externalities::call: AFTER: bal({})={}, bal({})={}\n", params.sender, self.state.balance(¶ms.sender), params.address, self.state.balance(¶ms.address)); match r { Ok(gas_left) => Ok((gas + gas_left, true)), diff --git a/src/state.rs b/src/state.rs index 98d1eacc3..88280c2da 100644 --- a/src/state.rs +++ b/src/state.rs @@ -107,16 +107,16 @@ impl State { /// Add `incr` to the balance of account `a`. pub fn add_balance(&mut self, a: &Address, incr: &U256) { -// let old = self.balance(a); + let old = self.balance(a); self.require(a, false).add_balance(incr); -// flush(format!("state: add_balance({}, {}): {} -> {}\n", a, incr, old, self.balance(a))); + trace!("state: add_balance({}, {}): {} -> {}\n", a, incr, old, self.balance(a)); } /// Subtract `decr` from the balance of account `a`. pub fn sub_balance(&mut self, a: &Address, decr: &U256) { -// let old = self.balance(a); + let old = self.balance(a); self.require(a, false).sub_balance(decr); -// flush(format!("state: sub_balance({}, {}): {} -> {}\n", a, decr, old, self.balance(a))); + trace!("state: sub_balance({}, {}): {} -> {}\n", a, decr, old, self.balance(a)); } /// Subtracts `by` from the balance of `from` and adds it to that of `to`. @@ -230,13 +230,6 @@ impl State { /// `require_code` requires that the code be cached, too. fn get(&self, a: &Address, require_code: bool) -> Ref> { self.cache.borrow_mut().entry(a.clone()).or_insert_with(|| { - /*{ - let orlp = SecTrieDB::new(&self.db, &self.root).get(&a).map(|rlp| rlp.to_vec()); - if let Some(rlp) = orlp { - let acc = Account::from_rlp(&rlp); - flush(format!("State::get({}) -> {} (bal={})\n", a, rlp.pretty(), acc.balance())); - } - }*/ SecTrieDB::new(&self.db, &self.root).get(&a).map(|rlp| Account::from_rlp(rlp)) }); if require_code {