Fixing delegatecall
This commit is contained in:
parent
98b49e0234
commit
aa0760597b
@ -23,15 +23,17 @@ pub struct ActionParams {
|
|||||||
pub gas_price: U256,
|
pub gas_price: U256,
|
||||||
/// Transaction value.
|
/// Transaction value.
|
||||||
pub value: U256,
|
pub value: U256,
|
||||||
|
/// Should transfer value from sender to origin
|
||||||
|
pub is_value_transfer: bool,
|
||||||
/// Code being executed.
|
/// Code being executed.
|
||||||
pub code: Option<Bytes>,
|
pub code: Option<Bytes>,
|
||||||
/// Input data.
|
/// Input data.
|
||||||
pub data: Option<Bytes>
|
pub data: Option<Bytes>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActionParams {
|
impl Default for ActionParams {
|
||||||
/// TODO [Gav Wood] Please document me
|
/// Returns default ActionParams initialized with zeros
|
||||||
pub fn new() -> ActionParams {
|
fn default() -> ActionParams {
|
||||||
ActionParams {
|
ActionParams {
|
||||||
code_address: Address::new(),
|
code_address: Address::new(),
|
||||||
address: Address::new(),
|
address: Address::new(),
|
||||||
@ -41,7 +43,8 @@ impl ActionParams {
|
|||||||
gas_price: U256::zero(),
|
gas_price: U256::zero(),
|
||||||
value: U256::zero(),
|
value: U256::zero(),
|
||||||
code: None,
|
code: None,
|
||||||
data: None
|
data: None,
|
||||||
|
is_value_transfer: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ pub enum MessageCallResult {
|
|||||||
Failed
|
Failed
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO [debris] Please document me
|
/// Externalities interface for EVMs
|
||||||
pub trait Ext {
|
pub trait Ext {
|
||||||
/// Returns a value for given key.
|
/// Returns a value for given key.
|
||||||
fn storage_at(&self, key: &H256) -> H256;
|
fn storage_at(&self, key: &H256) -> H256;
|
||||||
@ -61,6 +61,18 @@ pub trait Ext {
|
|||||||
code_address: &Address,
|
code_address: &Address,
|
||||||
output: &mut [u8]) -> MessageCallResult;
|
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,
|
||||||
|
value: &U256,
|
||||||
|
data: &[u8],
|
||||||
|
code_address: &Address,
|
||||||
|
output: &mut [u8]) -> MessageCallResult;
|
||||||
|
|
||||||
/// Returns code at given address
|
/// Returns code at given address
|
||||||
fn extcode(&self, address: &Address) -> Bytes;
|
fn extcode(&self, address: &Address) -> Bytes;
|
||||||
|
|
||||||
|
@ -564,17 +564,50 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
instructions::CALL | instructions::CALLCODE | instructions::DELEGATECALL => {
|
instructions::DELEGATECALL => {
|
||||||
|
let call_gas = stack.pop_back();
|
||||||
|
let code_address = stack.pop_back();
|
||||||
|
let code_address = u256_to_address(&code_address);
|
||||||
|
|
||||||
|
let value = params.value;
|
||||||
|
|
||||||
|
let in_off = stack.pop_back();
|
||||||
|
let in_size = stack.pop_back();
|
||||||
|
let out_off = stack.pop_back();
|
||||||
|
let out_size = stack.pop_back();
|
||||||
|
|
||||||
|
let can_call = ext.depth() < ext.schedule().max_depth;
|
||||||
|
if !can_call {
|
||||||
|
stack.push(U256::zero());
|
||||||
|
return Ok(InstructionResult::UnusedGas(call_gas));
|
||||||
|
}
|
||||||
|
|
||||||
|
let call_result = {
|
||||||
|
// we need to write and read from memory in the same time
|
||||||
|
// and we don't want to copy
|
||||||
|
let input = unsafe { ::std::mem::transmute(mem.read_slice(in_off, in_size)) };
|
||||||
|
let output = mem.writeable_slice(out_off, out_size);
|
||||||
|
ext.delegatecall(&call_gas, &value, input, &code_address, output)
|
||||||
|
};
|
||||||
|
|
||||||
|
return match call_result {
|
||||||
|
MessageCallResult::Success(gas_left) => {
|
||||||
|
stack.push(U256::one());
|
||||||
|
Ok(InstructionResult::UnusedGas(gas_left))
|
||||||
|
},
|
||||||
|
MessageCallResult::Failed => {
|
||||||
|
stack.push(U256::zero());
|
||||||
|
Ok(InstructionResult::Ok)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
instructions::CALL | instructions::CALLCODE => {
|
||||||
assert!(ext.schedule().call_value_transfer_gas > ext.schedule().call_stipend, "overflow possible");
|
assert!(ext.schedule().call_value_transfer_gas > ext.schedule().call_stipend, "overflow possible");
|
||||||
let call_gas = stack.pop_back();
|
let call_gas = stack.pop_back();
|
||||||
let code_address = stack.pop_back();
|
let code_address = stack.pop_back();
|
||||||
let code_address = u256_to_address(&code_address);
|
let code_address = u256_to_address(&code_address);
|
||||||
let is_delegatecall = instruction == instructions::DELEGATECALL;
|
|
||||||
|
|
||||||
let value = match is_delegatecall {
|
let value = stack.pop_back();
|
||||||
true => params.value,
|
|
||||||
false => stack.pop_back()
|
|
||||||
};
|
|
||||||
|
|
||||||
let address = match instruction == instructions::CALL {
|
let address = match instruction == instructions::CALL {
|
||||||
true => &code_address,
|
true => &code_address,
|
||||||
@ -586,12 +619,12 @@ impl Interpreter {
|
|||||||
let out_off = stack.pop_back();
|
let out_off = stack.pop_back();
|
||||||
let out_size = stack.pop_back();
|
let out_size = stack.pop_back();
|
||||||
|
|
||||||
let call_gas = call_gas + match !is_delegatecall && value > U256::zero() {
|
let call_gas = call_gas + match value > U256::zero() {
|
||||||
true => U256::from(ext.schedule().call_stipend),
|
true => U256::from(ext.schedule().call_stipend),
|
||||||
false => U256::zero()
|
false => U256::zero()
|
||||||
};
|
};
|
||||||
|
|
||||||
let can_call = (is_delegatecall || ext.balance(¶ms.address) >= value) && ext.depth() < ext.schedule().max_depth;
|
let can_call = ext.balance(¶ms.address) >= value && ext.depth() < ext.schedule().max_depth;
|
||||||
|
|
||||||
if !can_call {
|
if !can_call {
|
||||||
stack.push(U256::zero());
|
stack.push(U256::zero());
|
||||||
|
@ -69,6 +69,15 @@ impl Ext for FakeExt {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delegatecall(&mut self,
|
||||||
|
_gas: &U256,
|
||||||
|
_value: &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()
|
||||||
}
|
}
|
||||||
@ -110,7 +119,7 @@ fn test_stack_underflow() {
|
|||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "01600055".from_hex().unwrap();
|
let code = "01600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -137,7 +146,7 @@ fn test_add(factory: super::Factory) {
|
|||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
|
let code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -157,7 +166,7 @@ fn test_sha3(factory: super::Factory) {
|
|||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "6000600020600055".from_hex().unwrap();
|
let code = "6000600020600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -177,7 +186,7 @@ fn test_address(factory: super::Factory) {
|
|||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "30600055".from_hex().unwrap();
|
let code = "30600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -198,7 +207,7 @@ fn test_origin(factory: super::Factory) {
|
|||||||
let origin = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
let origin = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let code = "32600055".from_hex().unwrap();
|
let code = "32600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -220,7 +229,7 @@ fn test_sender(factory: super::Factory) {
|
|||||||
let sender = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let code = "33600055".from_hex().unwrap();
|
let code = "33600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -254,7 +263,7 @@ fn test_extcodecopy(factory: super::Factory) {
|
|||||||
let code = "333b60006000333c600051600055".from_hex().unwrap();
|
let code = "333b60006000333c600051600055".from_hex().unwrap();
|
||||||
let sender_code = "6005600055".from_hex().unwrap();
|
let sender_code = "6005600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -276,7 +285,7 @@ fn test_log_empty(factory: super::Factory) {
|
|||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "60006000a0".from_hex().unwrap();
|
let code = "60006000a0".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -307,7 +316,7 @@ fn test_log_sender(factory: super::Factory) {
|
|||||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let code = "60ff6000533360206000a1".from_hex().unwrap();
|
let code = "60ff6000533360206000a1".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -332,7 +341,7 @@ fn test_blockhash(factory: super::Factory) {
|
|||||||
let code = "600040600055".from_hex().unwrap();
|
let code = "600040600055".from_hex().unwrap();
|
||||||
let blockhash = H256::from_str("123400000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
let blockhash = H256::from_str("123400000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -354,7 +363,7 @@ fn test_calldataload(factory: super::Factory) {
|
|||||||
let code = "600135600055".from_hex().unwrap();
|
let code = "600135600055".from_hex().unwrap();
|
||||||
let data = "0123ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23".from_hex().unwrap();
|
let data = "0123ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
@ -376,7 +385,7 @@ fn test_author(factory: super::Factory) {
|
|||||||
let author = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let author = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let code = "41600055".from_hex().unwrap();
|
let code = "41600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
@ -396,7 +405,7 @@ fn test_timestamp(factory: super::Factory) {
|
|||||||
let timestamp = 0x1234;
|
let timestamp = 0x1234;
|
||||||
let code = "42600055".from_hex().unwrap();
|
let code = "42600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
@ -416,7 +425,7 @@ fn test_number(factory: super::Factory) {
|
|||||||
let number = 0x1234;
|
let number = 0x1234;
|
||||||
let code = "43600055".from_hex().unwrap();
|
let code = "43600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
@ -436,7 +445,7 @@ fn test_difficulty(factory: super::Factory) {
|
|||||||
let difficulty = U256::from(0x1234);
|
let difficulty = U256::from(0x1234);
|
||||||
let code = "44600055".from_hex().unwrap();
|
let code = "44600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
@ -456,7 +465,7 @@ fn test_gas_limit(factory: super::Factory) {
|
|||||||
let gas_limit = U256::from(0x1234);
|
let gas_limit = U256::from(0x1234);
|
||||||
let code = "45600055".from_hex().unwrap();
|
let code = "45600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code);
|
params.code = Some(code);
|
||||||
let mut ext = FakeExt::new();
|
let mut ext = FakeExt::new();
|
||||||
|
@ -134,6 +134,7 @@ impl<'a> Executive<'a> {
|
|||||||
gas: init_gas,
|
gas: init_gas,
|
||||||
gas_price: t.gas_price,
|
gas_price: t.gas_price,
|
||||||
value: t.value,
|
value: t.value,
|
||||||
|
is_value_transfer: true,
|
||||||
code: Some(t.data.clone()),
|
code: Some(t.data.clone()),
|
||||||
data: None,
|
data: None,
|
||||||
};
|
};
|
||||||
@ -148,6 +149,7 @@ impl<'a> Executive<'a> {
|
|||||||
gas: init_gas,
|
gas: init_gas,
|
||||||
gas_price: t.gas_price,
|
gas_price: t.gas_price,
|
||||||
value: t.value,
|
value: t.value,
|
||||||
|
is_value_transfer: true,
|
||||||
code: self.state.code(address),
|
code: self.state.code(address),
|
||||||
data: Some(t.data.clone()),
|
data: Some(t.data.clone()),
|
||||||
};
|
};
|
||||||
@ -166,11 +168,14 @@ impl<'a> Executive<'a> {
|
|||||||
/// Modifies the substate and the output.
|
/// Modifies the substate and the output.
|
||||||
/// Returns either gas_left or `evm::Error`.
|
/// Returns either gas_left or `evm::Error`.
|
||||||
pub fn call(&mut self, params: ActionParams, substate: &mut Substate, mut output: BytesRef) -> evm::Result {
|
pub fn call(&mut self, params: ActionParams, substate: &mut Substate, mut output: BytesRef) -> evm::Result {
|
||||||
|
println!("Calling executive. Sender: {}", params.sender);
|
||||||
// backup used in case of running out of gas
|
// backup used in case of running out of gas
|
||||||
let backup = self.state.clone();
|
let backup = self.state.clone();
|
||||||
|
|
||||||
// at first, transfer value to destination
|
// at first, transfer value to destination
|
||||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
if params.is_value_transfer {
|
||||||
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
}
|
||||||
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
|
trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info);
|
||||||
|
|
||||||
if self.engine.is_builtin(¶ms.code_address) {
|
if self.engine.is_builtin(¶ms.code_address) {
|
||||||
@ -227,7 +232,9 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.new_contract(¶ms.address);
|
self.state.new_contract(¶ms.address);
|
||||||
|
|
||||||
// then transfer value to it
|
// then transfer value to it
|
||||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
if params.is_value_transfer {
|
||||||
|
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value);
|
||||||
|
}
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ext = self.to_externalities(OriginInfo::from(¶ms), &mut unconfirmed_substate, OutputPolicy::InitContract);
|
let mut ext = self.to_externalities(OriginInfo::from(¶ms), &mut unconfirmed_substate, OutputPolicy::InitContract);
|
||||||
@ -367,7 +374,7 @@ mod tests {
|
|||||||
fn test_sender_balance(factory: Factory) {
|
fn test_sender_balance(factory: Factory) {
|
||||||
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -424,7 +431,7 @@ mod tests {
|
|||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
// TODO: add tests for 'callcreate'
|
// TODO: add tests for 'callcreate'
|
||||||
//let next_address = contract_address(&address, &U256::zero());
|
//let next_address = contract_address(&address, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
@ -477,7 +484,7 @@ mod tests {
|
|||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
// TODO: add tests for 'callcreate'
|
// TODO: add tests for 'callcreate'
|
||||||
//let next_address = contract_address(&address, &U256::zero());
|
//let next_address = contract_address(&address, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
@ -528,7 +535,7 @@ mod tests {
|
|||||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
let next_address = contract_address(&address, &U256::zero());
|
let next_address = contract_address(&address, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
@ -584,7 +591,7 @@ mod tests {
|
|||||||
let address_b = Address::from_str("945304eb96065b2a98b57a48a06ae28d285a71b5" ).unwrap();
|
let address_b = Address::from_str("945304eb96065b2a98b57a48a06ae28d285a71b5" ).unwrap();
|
||||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
|
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
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);
|
||||||
@ -633,7 +640,7 @@ mod tests {
|
|||||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap();
|
let code = "600160005401600055600060006000600060003060e05a03f1600155".from_hex().unwrap();
|
||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.gas = U256::from(100_000);
|
params.gas = U256::from(100_000);
|
||||||
params.code = Some(code.clone());
|
params.code = Some(code.clone());
|
||||||
@ -789,7 +796,7 @@ mod tests {
|
|||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
// TODO: add tests for 'callcreate'
|
// TODO: add tests for 'callcreate'
|
||||||
//let next_address = contract_address(&address, &U256::zero());
|
//let next_address = contract_address(&address, &U256::zero());
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
params.address = address.clone();
|
params.address = address.clone();
|
||||||
params.sender = sender.clone();
|
params.sender = sender.clone();
|
||||||
params.origin = sender.clone();
|
params.origin = sender.clone();
|
||||||
|
@ -17,6 +17,7 @@ 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,
|
||||||
address: Address,
|
address: Address,
|
||||||
origin: Address,
|
origin: Address,
|
||||||
gas_price: U256
|
gas_price: U256
|
||||||
@ -26,6 +27,7 @@ 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()
|
||||||
@ -112,6 +114,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
gas: *gas,
|
gas: *gas,
|
||||||
gas_price: self.origin_info.gas_price.clone(),
|
gas_price: self.origin_info.gas_price.clone(),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
|
is_value_transfer: true,
|
||||||
code: Some(code.to_vec()),
|
code: Some(code.to_vec()),
|
||||||
data: None,
|
data: None,
|
||||||
};
|
};
|
||||||
@ -129,6 +132,34 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delegatecall(&mut self,
|
||||||
|
gas: &U256,
|
||||||
|
value: &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: value.clone(),
|
||||||
|
is_value_transfer: false,
|
||||||
|
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,
|
address: &Address,
|
||||||
@ -145,6 +176,7 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
gas: *gas,
|
gas: *gas,
|
||||||
gas_price: self.origin_info.gas_price.clone(),
|
gas_price: self.origin_info.gas_price.clone(),
|
||||||
value: value.clone(),
|
value: value.clone(),
|
||||||
|
is_value_transfer: true,
|
||||||
code: self.state.code(code_address),
|
code: self.state.code(code_address),
|
||||||
data: Some(data.to_vec()),
|
data: Some(data.to_vec()),
|
||||||
};
|
};
|
||||||
|
@ -115,6 +115,22 @@ impl<'a> Ext for TestExt<'a> {
|
|||||||
MessageCallResult::Success(*gas)
|
MessageCallResult::Success(*gas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delegatecall(&mut self,
|
||||||
|
gas: &U256,
|
||||||
|
value: &U256,
|
||||||
|
data: &[u8],
|
||||||
|
_code_address: &Address,
|
||||||
|
_output: &mut [u8]) -> MessageCallResult {
|
||||||
|
|
||||||
|
self.callcreates.push(CallCreate {
|
||||||
|
data: data.to_vec(),
|
||||||
|
destination: None,
|
||||||
|
gas_limit: *gas,
|
||||||
|
value: *value
|
||||||
|
});
|
||||||
|
MessageCallResult::Success(*gas)
|
||||||
|
}
|
||||||
|
|
||||||
fn extcode(&self, address: &Address) -> Bytes {
|
fn extcode(&self, address: &Address) -> Bytes {
|
||||||
self.ext.extcode(address)
|
self.ext.extcode(address)
|
||||||
}
|
}
|
||||||
@ -200,7 +216,7 @@ fn do_json_test_for(vm: &VMType, json_data: &[u8]) -> Vec<String> {
|
|||||||
let engine = TestEngine::new(1, vm.clone());
|
let engine = TestEngine::new(1, vm.clone());
|
||||||
|
|
||||||
// params
|
// params
|
||||||
let mut params = ActionParams::new();
|
let mut params = ActionParams::default();
|
||||||
test.find("exec").map(|exec| {
|
test.find("exec").map(|exec| {
|
||||||
params.address = xjson!(&exec["address"]);
|
params.address = xjson!(&exec["address"]);
|
||||||
params.sender = xjson!(&exec["caller"]);
|
params.sender = xjson!(&exec["caller"]);
|
||||||
|
Loading…
Reference in New Issue
Block a user