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
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
fn log(&mut self, topics: Vec<H256>, data: &[u8]);

View File

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

View File

@ -140,6 +140,10 @@ impl Ext for FakeExt {
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]) {
self.logs.push(FakeLogEntry {
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![])
}
fn extcodesize(&self, address: &Address) -> usize {
self.state.code_size(address).unwrap_or(0)
}
#[cfg_attr(feature="dev", allow(match_ref_pats))]
fn ret(mut self, gas: &U256, data: &[u8]) -> evm::Result<U256>
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)
}
fn extcodesize(&self, address: &Address) -> usize {
self.ext.extcodesize(address)
}
fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
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> {
self.ensure_cached(a, true,
|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`.
pub fn add_balance(&mut self, a: &Address, incr: &U256) {
trace!(target: "state", "add_balance({}, {}): {}", a, incr, self.balance(a));