Separate path for ext code size (#2251)

* Separate path for code size

* Actually use it for EVM

* add extcodesize to TestExt
This commit is contained in:
Tomasz Drwięga 2016-09-22 19:58:42 +02:00 committed by Gav Wood
parent 723d837d05
commit aae6d19df9
6 changed files with 25 additions and 3 deletions

View File

@ -83,6 +83,9 @@ pub trait Ext {
/// Returns code at given address /// Returns code at given address
fn extcode(&self, address: &Address) -> Bytes; fn extcode(&self, address: &Address) -> Bytes;
/// Returns code size at given address
fn extcodesize(&self, address: &Address) -> usize;
/// Creates log entry with given topics and data /// Creates log entry with given topics and data
fn log(&mut self, topics: Vec<H256>, data: &[u8]); fn log(&mut self, topics: Vec<H256>, data: &[u8]);

View File

@ -471,7 +471,7 @@ impl<Cost: CostType> Interpreter<Cost> {
}, },
instructions::EXTCODESIZE => { instructions::EXTCODESIZE => {
let address = u256_to_address(&stack.pop_back()); let address = u256_to_address(&stack.pop_back());
let len = ext.extcode(&address).len(); let len = ext.extcodesize(&address);
stack.push(U256::from(len)); stack.push(U256::from(len));
}, },
instructions::CALLDATACOPY => { instructions::CALLDATACOPY => {

View File

@ -140,6 +140,10 @@ impl Ext for FakeExt {
self.codes.get(address).unwrap_or(&Bytes::new()).clone() self.codes.get(address).unwrap_or(&Bytes::new()).clone()
} }
fn extcodesize(&self, address: &Address) -> usize {
self.codes.get(address).map(|v| v.len()).unwrap_or(0)
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) { fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
self.logs.push(FakeLogEntry { self.logs.push(FakeLogEntry {
topics: topics, topics: topics,

View File

@ -205,6 +205,11 @@ impl<'a, T, V> Ext for Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMT
self.state.code(address).unwrap_or_else(|| vec![]) self.state.code(address).unwrap_or_else(|| vec![])
} }
fn extcodesize(&self, address: &Address) -> usize {
self.state.code_size(address).unwrap_or(0)
}
#[cfg_attr(feature="dev", allow(match_ref_pats))] #[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(mut self, gas: &U256, data: &[u8]) -> evm::Result<U256> fn ret(mut self, gas: &U256, data: &[u8]) -> evm::Result<U256>
where Self: Sized { where Self: Sized {

View File

@ -131,6 +131,10 @@ impl<'a, T, V> Ext for TestExt<'a, T, V> where T: Tracer, V: VMTracer {
self.ext.extcode(address) self.ext.extcode(address)
} }
fn extcodesize(&self, address: &Address) -> usize {
self.ext.extcodesize(address)
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) { fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
self.ext.log(topics, data) self.ext.log(topics, data)
} }

View File

@ -191,12 +191,18 @@ impl State {
})) }))
} }
/// Mutate storage of account `a` so that it is `value` for `key`. /// Get the code of account `a`.
pub fn code(&self, a: &Address) -> Option<Bytes> { pub fn code(&self, a: &Address) -> Option<Bytes> {
self.ensure_cached(a, true, self.ensure_cached(a, true,
|a| a.as_ref().map_or(None, |a| a.code().map(|x| x.to_vec()))) |a| a.as_ref().map_or(None, |a| a.code().map(|x| x.to_vec())))
} }
/// Get the code size of account `a`.
pub fn code_size(&self, a: &Address) -> Option<usize> {
self.ensure_cached(a, true,
|a| a.as_ref().map_or(None, |a| a.code().map(|x| x.len())))
}
/// 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) {
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a)); trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a));