diff --git a/src/context.cairo b/src/context.cairo index 65c2dcf58..6cb21df55 100644 --- a/src/context.cairo +++ b/src/context.cairo @@ -113,14 +113,13 @@ impl ExecutionContextImpl of ExecutionContextTrait { returned_data: Array, read_only: bool ) -> ExecutionContext { - let mut stack = StackTrait::new(); ExecutionContext { call_context, program_counter: 0, - stack: StackTrait::new(), + stack: Default::default(), stopped: false, - return_data: ArrayTrait::new(), - memory: MemoryTrait::new(), + return_data: Default::default(), + memory: Default::default(), gas_used: 0, gas_limit, gas_price, @@ -241,4 +240,3 @@ impl DefaultExecutionContext of Default { /// The execution summary. #[derive(Drop, Copy)] struct ExecutionSummary {} - diff --git a/src/model.cairo b/src/model.cairo index 82580ebe2..8ac93588b 100644 --- a/src/model.cairo +++ b/src/model.cairo @@ -3,4 +3,3 @@ struct Event { keys: Array, data: Array, } - diff --git a/src/tests/test_execution_context.cairo b/src/tests/test_execution_context.cairo index 6968f09a3..03c689e56 100644 --- a/src/tests/test_execution_context.cairo +++ b/src/tests/test_execution_context.cairo @@ -3,54 +3,92 @@ use traits::Into; use traits::TryInto; use option::OptionTrait; use debug::PrintTrait; +use traits::PartialEq; use array::{ArrayTrait, SpanTrait}; +use starknet::{EthAddress, ContractAddress}; +use starknet::testing::{set_contract_address, set_caller_address}; + use kakarot::memory::{Memory, MemoryTrait}; use kakarot::model::Event; use kakarot::stack::{Stack, StackTrait}; use kakarot::context::{CallContext, CallContextTrait, ExecutionContext, ExecutionContextTrait}; -use kakarot::utils::helpers::{SpanPartialEq}; -use traits::PartialEq; -use starknet::{EthAddress, ContractAddress}; +//TODO remove import once merged in corelib +use kakarot::utils::helpers::{SpanPartialEq, ArrayPartialEq}; +use kakarot::tests::test_utils::{setup_call_context, setup_execution_context, CallContextPartialEq}; use kakarot::tests::test_utils; -use starknet::testing::{set_contract_address, set_caller_address}; -fn setup_call_context() -> CallContext { +// TODO remove once no longer required (see https://github.com/starkware-libs/cairo/issues/3863) +#[inline(never)] +fn no_op() {} + + +#[test] +#[available_gas(1000000)] +fn test_call_context_new() { + // When let bytecode: Span = array![1, 2, 3].span(); let call_data: Span = array![4, 5, 6].span(); let value: u256 = 100; - CallContextTrait::new(bytecode, call_data, value) + let call_ctx = CallContextTrait::new(bytecode, call_data, value); + // TODO remove once no longer required (see https://github.com/starkware-libs/cairo/issues/3863) + no_op(); + + // Then + assert(call_ctx.bytecode() == bytecode, 'wrong bytecode'); + assert(call_ctx.call_data() == call_data, 'wrong call_data'); + assert(call_ctx.value() == value, 'wrong value'); } -fn setup_execution_context() -> ExecutionContext { +#[test] +#[available_gas(500000)] +fn test_execution_context_new() { + // Given let call_context = setup_call_context(); - let starknet_address: ContractAddress = test_utils::starknet_address(); - let evm_address: EthAddress = test_utils::evm_address(); + let program_counter: u32 = 0; + let stack = StackTrait::new(); + let stopped: bool = false; + let return_data: Array = ArrayTrait::new(); + let memory = MemoryTrait::new(); + let gas_used: u64 = 0; let gas_limit: u64 = 1000; let gas_price: u64 = 10; + let starknet_address: ContractAddress = 0.try_into().unwrap(); + let evm_address: EthAddress = 0.try_into().unwrap(); + let destroy_contracts: Array = Default::default(); + let events: Array = Default::default(); + let create_addresses: Array = Default::default(); + let revert_contract_state: Felt252Dict = Default::default(); + let reverted: bool = false; let read_only: bool = false; - let returned_data = Default::default(); - - ExecutionContextTrait::new( - call_context, starknet_address, evm_address, gas_limit, gas_price, returned_data, read_only - ) -} - -#[test] -#[available_gas(1000000)] -fn test_call_context_new() { // When - let call_context = setup_call_context(); -// Then -// TODO: uncomment once cairo-test bug is solved + let execution_context = ExecutionContextTrait::new( + call_context, starknet_address, evm_address, gas_limit, gas_price, return_data, read_only + ); -// assert(call_context.bytecode() == bytecode, 'wrong bytecode'); -// assert(call_context.value() == value, 'wrong value'); -// assert(call_context.call_data() == call_data, 'wrong call_data'); + // Then + let call_context = setup_call_context(); + assert(execution_context.call_context == call_context, 'wrong call_context'); + assert(execution_context.program_counter == program_counter, 'wrong program_counter'); + assert(execution_context.stack.is_empty(), 'wrong stack'); + assert(execution_context.stopped == stopped, 'wrong stopped'); + assert(execution_context.return_data == Default::default(), 'wrong return_data'); + assert(execution_context.memory.bytes_len == 0, 'wrong memory'); + assert(execution_context.gas_used == gas_used, 'wrong gas_used'); + assert(execution_context.gas_limit == gas_limit, 'wrong gas_limit'); + assert(execution_context.gas_price == gas_price, 'wrong gas_price'); + assert(execution_context.starknet_address == starknet_address, 'wrong starknet_address'); + assert(execution_context.evm_address == evm_address, 'wrong evm_address'); + assert(execution_context.destroy_contracts == destroy_contracts, 'wrong destroy_contracts'); + assert(execution_context.events.len() == events.len(), 'wrong events'); + assert(execution_context.create_addresses == create_addresses, 'wrong create_addresses'); + // Can't verify that reverted_contract_state is empty as we can't compare dictionaries directly + // But initializing it using `Default`, it will be empty. + assert(execution_context.reverted == reverted, 'wrong reverted'); + assert(execution_context.read_only == read_only, 'wrong read_only'); } - #[test] #[available_gas(100000)] fn test_execution_context_new_and_intrinsic_gas() { @@ -88,6 +126,7 @@ fn test_execution_context_revert() { // Then assert(execution_context.is_reverted() == true, 'should be reverted'); + assert(execution_context.return_data.span() == revert_reason, 'wrong revert reason'); } #[test] @@ -137,7 +176,6 @@ fn test_is_root() { #[test] #[available_gas(300000)] fn test_is_caller_eoa() { - // TODO: finish this test once calling_contexts are implemented // Given let mut execution_context = setup_execution_context(); diff --git a/src/tests/test_utils.cairo b/src/tests/test_utils.cairo index 3bea41d8f..cf08303d6 100644 --- a/src/tests/test_utils.cairo +++ b/src/tests/test_utils.cairo @@ -2,7 +2,7 @@ use starknet::{contract_address_try_from_felt252, ContractAddress, EthAddress}; use traits::{Into, TryInto}; use option::OptionTrait; use array::{ArrayTrait, SpanTrait}; - +use kakarot::utils::helpers::{SpanPartialEq}; use kakarot::context::{CallContext, CallContextTrait, ExecutionContext, ExecutionContextTrait}; mod test_helpers; @@ -41,3 +41,12 @@ fn setup_execution_context() -> ExecutionContext { call_context, starknet_address, evm_address, gas_limit, gas_price, returned_data, read_only ) } + +impl CallContextPartialEq of PartialEq { + fn eq(lhs: @CallContext, rhs: @CallContext) -> bool { + lhs.bytecode() == rhs.bytecode() && lhs.call_data == rhs.call_data && lhs.value == rhs.value + } + fn ne(lhs: @CallContext, rhs: @CallContext) -> bool { + !(lhs == rhs) + } +} diff --git a/src/utils/helpers.cairo b/src/utils/helpers.cairo index 7a27ee05d..dd8a66147 100644 --- a/src/utils/helpers.cairo +++ b/src/utils/helpers.cairo @@ -203,6 +203,7 @@ impl ArrayExtension of ArrayExtensionTrait { } } +//TODO remove once merged in corelib impl SpanPartialEq> of PartialEq> { fn eq(lhs: @Span, rhs: @Span) -> bool { if (*lhs).len() != (*rhs).len() { @@ -228,3 +229,12 @@ impl SpanPartialEq> of PartialEq> { } } +//TODO remove once merged in corelib +impl ArrayPartialEq> of PartialEq> { + fn eq(lhs: @Array, rhs: @Array) -> bool { + lhs.span() == rhs.span() + } + fn ne(lhs: @Array, rhs: @Array) -> bool { + !ArrayPartialEq::eq(lhs, rhs) + } +}