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