callcode builtins are working
This commit is contained in:
parent
ec7e80ff13
commit
ed0e243506
@ -9,6 +9,9 @@ use util::bytes::*;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ActionParams {
|
pub struct ActionParams {
|
||||||
/// Address of currently executed code.
|
/// Address of currently executed code.
|
||||||
|
pub code_address: Address,
|
||||||
|
/// Receive address. Usually equal to code_address,
|
||||||
|
/// except when called using CALLCODE.
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
/// Sender of current part of the transaction.
|
/// Sender of current part of the transaction.
|
||||||
pub sender: Address,
|
pub sender: Address,
|
||||||
@ -21,22 +24,23 @@ pub struct ActionParams {
|
|||||||
/// Transaction value.
|
/// Transaction value.
|
||||||
pub value: U256,
|
pub value: U256,
|
||||||
/// Code being executed.
|
/// Code being executed.
|
||||||
pub code: Bytes,
|
pub code: Option<Bytes>,
|
||||||
/// Input data.
|
/// Input data.
|
||||||
pub data: Bytes
|
pub data: Option<Bytes>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionParams {
|
impl ActionParams {
|
||||||
pub fn new() -> ActionParams {
|
pub fn new() -> ActionParams {
|
||||||
ActionParams {
|
ActionParams {
|
||||||
|
code_address: Address::new(),
|
||||||
address: Address::new(),
|
address: Address::new(),
|
||||||
sender: Address::new(),
|
sender: Address::new(),
|
||||||
origin: Address::new(),
|
origin: Address::new(),
|
||||||
gas: U256::zero(),
|
gas: U256::zero(),
|
||||||
gas_price: U256::zero(),
|
gas_price: U256::zero(),
|
||||||
value: U256::zero(),
|
value: U256::zero(),
|
||||||
code: vec![],
|
code: None,
|
||||||
data: vec![],
|
data: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,12 +310,12 @@ impl evm::Evm for JitEvm {
|
|||||||
let mut data = RuntimeData::new();
|
let mut data = RuntimeData::new();
|
||||||
data.gas = params.gas;
|
data.gas = params.gas;
|
||||||
data.gas_price = params.gas_price;
|
data.gas_price = params.gas_price;
|
||||||
data.call_data = params.data.clone();
|
data.call_data = params.data.clone().unwrap_or(vec![]);
|
||||||
data.address = params.address.clone();
|
data.address = params.address.clone();
|
||||||
data.caller = params.sender.clone();
|
data.caller = params.sender.clone();
|
||||||
data.origin = params.origin.clone();
|
data.origin = params.origin.clone();
|
||||||
data.call_value = params.value;
|
data.call_value = params.value;
|
||||||
data.code = params.code.clone();
|
data.code = params.code.clone().unwrap_or(vec![]);
|
||||||
|
|
||||||
data.author = ext.env_info().author.clone();
|
data.author = ext.env_info().author.clone();
|
||||||
data.difficulty = ext.env_info().difficulty;
|
data.difficulty = ext.env_info().difficulty;
|
||||||
|
@ -93,7 +93,7 @@ fn test_add() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -113,7 +113,7 @@ fn test_sha3() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -133,7 +133,7 @@ fn test_address() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -155,7 +155,7 @@ fn test_origin() {
|
|||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.origin = origin.clone();
|
params.origin = origin.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -177,7 +177,7 @@ fn test_sender() {
|
|||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -211,7 +211,7 @@ fn test_extcodecopy() {
|
|||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.codes.insert(sender, sender_code);
|
ext.codes.insert(sender, sender_code);
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ fn test_log_empty() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -264,7 +264,7 @@ fn test_log_sender() {
|
|||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -288,7 +288,7 @@ fn test_blockhash() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.blockhashes.insert(U256::zero(), blockhash.clone());
|
ext.blockhashes.insert(U256::zero(), blockhash.clone());
|
||||||
|
|
||||||
@ -310,8 +310,8 @@ fn test_calldataload() {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
params.data = data;
|
params.data = Some(data);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
@ -331,7 +331,7 @@ fn test_author() {
|
|||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.info.author = author;
|
ext.info.author = author;
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ fn test_timestamp() {
|
|||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.info.timestamp = timestamp;
|
ext.info.timestamp = timestamp;
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ fn test_number() {
|
|||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.info.number = number;
|
ext.info.number = number;
|
||||||
|
|
||||||
@ -391,7 +391,7 @@ fn test_difficulty() {
|
|||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.info.difficulty = difficulty;
|
ext.info.difficulty = difficulty;
|
||||||
|
|
||||||
@ -411,7 +411,7 @@ fn test_gas_limit() {
|
|||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code;
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
ext.info.gas_limit = gas_limit;
|
ext.info.gas_limit = gas_limit;
|
||||||
|
|
||||||
|
@ -150,28 +150,31 @@ impl<'a> Executive<'a> {
|
|||||||
|
|
||||||
let res = match t.action() {
|
let res = match t.action() {
|
||||||
&Action::Create => {
|
&Action::Create => {
|
||||||
|
let new_address = contract_address(&sender, &nonce);
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
address: contract_address(&sender, &nonce),
|
code_address: new_address.clone(),
|
||||||
|
address: new_address,
|
||||||
sender: sender.clone(),
|
sender: sender.clone(),
|
||||||
origin: sender.clone(),
|
origin: sender.clone(),
|
||||||
gas: init_gas,
|
gas: init_gas,
|
||||||
gas_price: t.gas_price,
|
gas_price: t.gas_price,
|
||||||
value: t.value,
|
value: t.value,
|
||||||
code: t.data.clone(),
|
code: Some(t.data.clone()),
|
||||||
data: vec![],
|
data: None,
|
||||||
};
|
};
|
||||||
self.create(¶ms, &mut substate)
|
self.create(¶ms, &mut substate)
|
||||||
},
|
},
|
||||||
&Action::Call(ref address) => {
|
&Action::Call(ref address) => {
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
|
code_address: address.clone(),
|
||||||
address: address.clone(),
|
address: address.clone(),
|
||||||
sender: sender.clone(),
|
sender: sender.clone(),
|
||||||
origin: sender.clone(),
|
origin: sender.clone(),
|
||||||
gas: init_gas,
|
gas: init_gas,
|
||||||
gas_price: t.gas_price,
|
gas_price: t.gas_price,
|
||||||
value: t.value,
|
value: t.value,
|
||||||
code: self.state.code(address).unwrap_or(vec![]),
|
code: self.state.code(address),
|
||||||
data: t.data.clone(),
|
data: Some(t.data.clone()),
|
||||||
};
|
};
|
||||||
// TODO: move output upstream
|
// TODO: move output upstream
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
@ -194,12 +197,14 @@ impl<'a> Executive<'a> {
|
|||||||
// at first, transfer value to destination
|
// at first, transfer value to destination
|
||||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
|
||||||
if self.engine.is_builtin(¶ms.address) {
|
if self.engine.is_builtin(¶ms.code_address) {
|
||||||
|
let default = [];
|
||||||
|
let data = if let &Some(ref d) = ¶ms.data { d as &[u8] } else { &default as &[u8] };
|
||||||
// if destination is builtin, try to execute it
|
// if destination is builtin, try to execute it
|
||||||
let cost = self.engine.cost_of_builtin(¶ms.address, ¶ms.data);
|
let cost = self.engine.cost_of_builtin(¶ms.code_address, &data);
|
||||||
match cost <= params.gas {
|
match cost <= params.gas {
|
||||||
true => {
|
true => {
|
||||||
self.engine.execute_builtin(¶ms.address, ¶ms.data, &mut output);
|
self.engine.execute_builtin(¶ms.code_address, &data, &mut output);
|
||||||
Ok(params.gas - cost)
|
Ok(params.gas - cost)
|
||||||
},
|
},
|
||||||
// just drain the whole gas
|
// just drain the whole gas
|
||||||
@ -208,7 +213,7 @@ impl<'a> Executive<'a> {
|
|||||||
Err(evm::Error::OutOfGas)
|
Err(evm::Error::OutOfGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if params.code.len() > 0 {
|
} else if params.code.is_some() {
|
||||||
// if destination is a contract, do normal message call
|
// if destination is a contract, do normal message call
|
||||||
|
|
||||||
// part of substate that may be reverted
|
// part of substate that may be reverted
|
||||||
@ -411,14 +416,15 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
|
|
||||||
// prepare the params
|
// prepare the params
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
|
code_address: address.clone(),
|
||||||
address: address.clone(),
|
address: address.clone(),
|
||||||
sender: self.params.address.clone(),
|
sender: self.params.address.clone(),
|
||||||
origin: self.params.origin.clone(),
|
origin: self.params.origin.clone(),
|
||||||
gas: *gas,
|
gas: *gas,
|
||||||
gas_price: self.params.gas_price.clone(),
|
gas_price: self.params.gas_price.clone(),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
code: code.to_vec(),
|
code: Some(code.to_vec()),
|
||||||
data: vec![],
|
data: None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
||||||
@ -440,6 +446,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
let mut gas_cost = *call_gas;
|
let mut gas_cost = *call_gas;
|
||||||
let mut call_gas = *call_gas;
|
let mut call_gas = *call_gas;
|
||||||
|
|
||||||
|
// TODO: move gas calculation out!
|
||||||
let is_call = receive_address == code_address;
|
let is_call = receive_address == code_address;
|
||||||
if is_call && !self.state.exists(&code_address) {
|
if is_call && !self.state.exists(&code_address) {
|
||||||
gas_cost = gas_cost + U256::from(self.schedule.call_new_account_gas);
|
gas_cost = gas_cost + U256::from(self.schedule.call_new_account_gas);
|
||||||
@ -463,14 +470,15 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
|
code_address: code_address.clone(),
|
||||||
address: receive_address.clone(),
|
address: receive_address.clone(),
|
||||||
sender: self.params.address.clone(),
|
sender: self.params.address.clone(),
|
||||||
origin: self.params.origin.clone(),
|
origin: self.params.origin.clone(),
|
||||||
gas: call_gas,
|
gas: call_gas,
|
||||||
gas_price: self.params.gas_price.clone(),
|
gas_price: self.params.gas_price.clone(),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
code: self.state.code(code_address).unwrap_or(vec![]),
|
code: self.state.code(code_address),
|
||||||
data: data.to_vec(),
|
data: Some(data.to_vec()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
|
||||||
@ -591,7 +599,7 @@ mod tests {
|
|||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = "3331600055".from_hex().unwrap();
|
params.code = Some("3331600055".from_hex().unwrap());
|
||||||
params.value = U256::from(0x7);
|
params.value = U256::from(0x7);
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.add_balance(&sender, &U256::from(0x100u64));
|
state.add_balance(&sender, &U256::from(0x100u64));
|
||||||
@ -649,7 +657,7 @@ mod tests {
|
|||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code.clone();
|
params.code = Some(code.clone());
|
||||||
params.value = U256::from(100);
|
params.value = U256::from(100);
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
@ -702,7 +710,7 @@ mod tests {
|
|||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code.clone();
|
params.code = Some(code.clone());
|
||||||
params.value = U256::from(100);
|
params.value = U256::from(100);
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
@ -753,7 +761,7 @@ mod tests {
|
|||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code.clone();
|
params.code = Some(code.clone());
|
||||||
params.value = U256::from(100);
|
params.value = U256::from(100);
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
@ -807,7 +815,7 @@ mod tests {
|
|||||||
params.address = address_a.clone();
|
params.address = address_a.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code_a.clone();
|
params.code = Some(code_a.clone());
|
||||||
params.value = U256::from(100_000);
|
params.value = U256::from(100_000);
|
||||||
|
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
@ -854,7 +862,7 @@ mod tests {
|
|||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::new();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = code.clone();
|
params.code = Some(code.clone());
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.init_code(&address, code.clone());
|
state.init_code(&address, code.clone());
|
||||||
let info = EnvInfo::new();
|
let info = EnvInfo::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user