Changing delegatecall logic

This commit is contained in:
Tomusdrw 2016-01-23 10:41:13 +01:00
parent fbb57b1c1b
commit e27d628e75
6 changed files with 30 additions and 84 deletions

View File

@ -21,7 +21,7 @@ evmjit = { path = "rust-evmjit", optional = true }
ethash = { path = "ethash" } ethash = { path = "ethash" }
num_cpus = "0.2" num_cpus = "0.2"
ctrlc = "1.0" ctrlc = "1.0"
clippy = "*" # Always newest, since we use nightly clippy = "0.0.37" # Always newest, since we use nightly
[features] [features]
jit = ["evmjit"] jit = ["evmjit"]

View File

@ -55,19 +55,9 @@ pub trait Ext {
/// and true if subcall was successfull. /// and true if subcall was successfull.
fn call(&mut self, fn call(&mut self,
gas: &U256, gas: &U256,
address: &Address, sender_address: &Address,
value: &U256, receive_address: &Address,
data: &[u8], value: Option<&U256>,
code_address: &Address,
output: &mut [u8]) -> MessageCallResult;
/// Delegate Message call.
///
/// Returns Err, if we run out of gas.
/// Otherwise returns call_result which contains gas left
/// and true if subcall was successfull.
fn delegatecall(&mut self,
gas: &U256,
data: &[u8], data: &[u8],
code_address: &Address, code_address: &Address,
output: &mut [u8]) -> MessageCallResult; output: &mut [u8]) -> MessageCallResult;

View File

@ -587,7 +587,7 @@ impl Interpreter {
// and we don't want to copy // and we don't want to copy
let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) }; let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) };
let output = mem.writeable_slice(out_off, out_size); let output = mem.writeable_slice(out_off, out_size);
ext.delegatecall(&call_gas, input, &code_address, output) ext.call(&call_gas, &params.sender, &params.address, None, input, &code_address, output)
}; };
return match call_result { return match call_result {
@ -609,11 +609,6 @@ impl Interpreter {
let value = stack.pop_back(); let value = stack.pop_back();
let address = match instruction == instructions::CALL {
true => &code_address,
false => &params.address
};
let in_off = stack.pop_back(); let in_off = stack.pop_back();
let in_size = stack.pop_back(); let in_size = stack.pop_back();
let out_off = stack.pop_back(); let out_off = stack.pop_back();
@ -624,6 +619,11 @@ impl Interpreter {
false => U256::zero() false => U256::zero()
}; };
let (sender_address, receive_address) = match instruction == instructions::CALL {
true => (&params.address, &code_address),
false => (&params.address, &params.address)
};
let can_call = ext.balance(&params.address) >= value && ext.depth() < ext.schedule().max_depth; let can_call = ext.balance(&params.address) >= value && ext.depth() < ext.schedule().max_depth;
if !can_call { if !can_call {
@ -636,7 +636,7 @@ impl Interpreter {
// and we don't want to copy // and we don't want to copy
let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) }; let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) };
let output = mem.writeable_slice(out_off, out_size); let output = mem.writeable_slice(out_off, out_size);
ext.call(&call_gas, address, &value, input, &code_address, output) ext.call(&call_gas, sender_address, receive_address, Some(&value), input, &code_address, output)
}; };
return match call_result { return match call_result {

View File

@ -61,22 +61,15 @@ impl Ext for FakeExt {
fn call(&mut self, fn call(&mut self,
_gas: &U256, _gas: &U256,
_address: &Address, _sender_address: &Address,
_value: &U256, _receive_address: &Address,
_value: Option<&U256>,
_data: &[u8], _data: &[u8],
_code_address: &Address, _code_address: &Address,
_output: &mut [u8]) -> MessageCallResult { _output: &mut [u8]) -> MessageCallResult {
unimplemented!(); unimplemented!();
} }
fn delegatecall(&mut self,
_gas: &U256,
_data: &[u8],
_address: &Address,
_output: &mut [u8]) -> MessageCallResult {
unimplemented!();
}
fn extcode(&self, address: &Address) -> Bytes { fn extcode(&self, address: &Address) -> Bytes {
self.codes.get(address).unwrap_or(&Bytes::new()).clone() self.codes.get(address).unwrap_or(&Bytes::new()).clone()
} }

View File

@ -17,18 +17,16 @@ pub enum OutputPolicy<'a> {
/// Transaction properties that externalities need to know about. /// Transaction properties that externalities need to know about.
pub struct OriginInfo { pub struct OriginInfo {
sender: Address,
value: U256,
address: Address, address: Address,
origin: Address, origin: Address,
gas_price: U256 gas_price: U256,
value: U256
} }
impl OriginInfo { impl OriginInfo {
/// Populates origin info from action params. /// Populates origin info from action params.
pub fn from(params: &ActionParams) -> Self { pub fn from(params: &ActionParams) -> Self {
OriginInfo { OriginInfo {
sender: params.sender.clone(),
address: params.address.clone(), address: params.address.clone(),
origin: params.origin.clone(), origin: params.origin.clone(),
gas_price: params.gas_price.clone(), gas_price: params.gas_price.clone(),
@ -136,52 +134,31 @@ impl<'a> Ext for Externalities<'a> {
} }
} }
fn delegatecall(&mut self,
gas: &U256,
data: &[u8],
code_address: &Address,
output: &mut [u8]) -> MessageCallResult {
let params = ActionParams {
code_address: code_address.clone(),
address: self.origin_info.address.clone(),
sender: self.origin_info.sender.clone(),
origin: self.origin_info.origin.clone(),
gas: *gas,
gas_price: self.origin_info.gas_price.clone(),
value: ActionValue::Apparent(self.origin_info.value.clone()),
code: self.state.code(code_address),
data: Some(data.to_vec()),
};
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth);
match ex.call(params, self.substate, BytesRef::Fixed(output)) {
Ok(gas_left) => MessageCallResult::Success(gas_left),
_ => MessageCallResult::Failed
}
}
fn call(&mut self, fn call(&mut self,
gas: &U256, gas: &U256,
address: &Address, sender_address: &Address,
value: &U256, receive_address: &Address,
value: Option<&U256>,
data: &[u8], data: &[u8],
code_address: &Address, code_address: &Address,
output: &mut [u8]) -> MessageCallResult { output: &mut [u8]) -> MessageCallResult {
let params = ActionParams { let mut params = ActionParams {
sender: sender_address.clone(),
address: receive_address.clone(),
value: ActionValue::Apparent(self.origin_info.value.clone()),
code_address: code_address.clone(), code_address: code_address.clone(),
address: address.clone(),
sender: self.origin_info.address.clone(),
origin: self.origin_info.origin.clone(), origin: self.origin_info.origin.clone(),
gas: *gas, gas: *gas,
gas_price: self.origin_info.gas_price.clone(), gas_price: self.origin_info.gas_price.clone(),
value: ActionValue::Transfer(value.clone()),
code: self.state.code(code_address), code: self.state.code(code_address),
data: Some(data.to_vec()), data: Some(data.to_vec()),
}; };
if let Some(value) = value {
params.value = ActionValue::Transfer(value.clone());
}
let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth); let mut ex = Executive::from_parent(self.state, self.env_info, self.engine, self.depth);
match ex.call(params, self.substate, BytesRef::Fixed(output)) { match ex.call(params, self.substate, BytesRef::Fixed(output)) {

View File

@ -101,8 +101,9 @@ impl<'a> Ext for TestExt<'a> {
fn call(&mut self, fn call(&mut self,
gas: &U256, gas: &U256,
_sender_address: &Address,
receive_address: &Address, receive_address: &Address,
value: &U256, value: Option<&U256>,
data: &[u8], data: &[u8],
_code_address: &Address, _code_address: &Address,
_output: &mut [u8]) -> MessageCallResult { _output: &mut [u8]) -> MessageCallResult {
@ -110,22 +111,7 @@ impl<'a> Ext for TestExt<'a> {
data: data.to_vec(), data: data.to_vec(),
destination: Some(receive_address.clone()), destination: Some(receive_address.clone()),
gas_limit: *gas, gas_limit: *gas,
value: *value value: *value.unwrap()
});
MessageCallResult::Success(*gas)
}
fn delegatecall(&mut self,
gas: &U256,
data: &[u8],
_code_address: &Address,
_output: &mut [u8]) -> MessageCallResult {
self.callcreates.push(CallCreate {
data: data.to_vec(),
destination: None,
gas_limit: *gas,
value: U256::zero()
}); });
MessageCallResult::Success(*gas) MessageCallResult::Success(*gas)
} }