From 1c61d7c813e03072bd1eb8cf5bde682427759588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 28 Sep 2016 23:33:12 +0200 Subject: [PATCH] Fixing Delegate Call in JIT (#2378) * Detecting DELEGATE_CALL in JIT * Fixing evmjit tests --- ethcore/src/evm/jit.rs | 14 ++++++++------ ethcore/src/executive.rs | 13 +++++++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ethcore/src/evm/jit.rs b/ethcore/src/evm/jit.rs index c62f87ab7..3487d9a59 100644 --- a/ethcore/src/evm/jit.rs +++ b/ethcore/src/evm/jit.rs @@ -196,6 +196,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { receive_address: *const evmjit::H256, code_address: *const evmjit::H256, transfer_value: *const evmjit::I256, + // We are ignoring apparent value - it's handled in externalities. _apparent_value: *const evmjit::I256, in_beg: *const u8, in_size: u64, @@ -208,12 +209,13 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { let sender_address = unsafe { Address::from_jit(&*sender_address) }; let receive_address = unsafe { Address::from_jit(&*receive_address) }; let code_address = unsafe { Address::from_jit(&*code_address) }; - // TODO Is it always safe in case of DELEGATE_CALL? let transfer_value = unsafe { U256::from_jit(&*transfer_value) }; - let value = Some(transfer_value); // receive address and code address are the same in normal calls let is_callcode = receive_address != code_address; + let is_delegatecall = is_callcode && sender_address != receive_address; + + let value = if is_delegatecall { None } else { Some(transfer_value) }; if !is_callcode && !self.ext.exists(&code_address) { gas_cost = gas_cost + U256::from(self.ext.schedule().call_new_account_gas); @@ -242,10 +244,10 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { } } - // TODO [ToDr] Any way to detect DelegateCall? - let call_type = match is_callcode { - true => CallType::CallCode, - false => CallType::Call, + let call_type = match (is_callcode, is_delegatecall) { + (_, true) => CallType::DelegateCall, + (true, false) => CallType::CallCode, + (false, false) => CallType::Call, }; match self.ext.call( diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 8f8b534ee..6a7e4672a 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -589,8 +589,11 @@ mod tests { assert_eq!(substate.contracts_created.len(), 0); } - evm_test!{test_call_to_create: test_call_to_create_jit, test_call_to_create_int} - fn test_call_to_create(factory: Factory) { + #[test] + // Tracing is not suported in JIT + fn test_call_to_create() { + let factory = Factory::new(VMType::Interpreter); + // code: // // 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes? @@ -712,8 +715,10 @@ mod tests { assert_eq!(vm_tracer.drain().unwrap(), expected_vm_trace); } - evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int} - fn test_create_contract(factory: Factory) { + #[test] + fn test_create_contract() { + // Tracing is not supported in JIT + let factory = Factory::new(VMType::Interpreter); // code: // // 60 10 - push 16