lambdaclass / cairo-vm

cairo-vm is a Rust implementation of the Cairo VM. Cairo (CPU Algebraic Intermediate Representation) is a programming language for writing provable programs, where one party can prove to another that a certain computation was executed correctly without the need for this party to re-execute the same program.
https://lambdaclass.github.io/cairo-vm
Apache License 2.0
517 stars 148 forks source link

Incorrect Serialization of Struct Return Values in Cairo1 Run #1564

Closed raphaelDkhn closed 9 months ago

raphaelDkhn commented 9 months ago

Describe the bug

I'm encountering an issue with struct serialization when running a Cairo1 program with cairo1-run. When a struct is returned from the program, the serialized return does not match the expected output. Here's the Cairo program I'm testing:

Here is the cairo program I'm testing:

use core::array::SpanTrait;

#[derive(Copy, Drop)]
struct Tensor {
    shape: Span<u32>,
    data: Span<u32>
}

fn main() -> Tensor {
    let tensor = Tensor {
    shape: array![2, 2].span(),
    data: array![1, 2, 3, 4].span(),
    };

    tensor
}

After running cargo run ../cairo_programs/cairo-1-programs/tensor.cairo --layout all_cairo --args '[2 2] [1 2 3 4]' it returns:

Return values : [5:0, 5:2, 6:0, 6:4]

However, I expected it to return:

Return values : 
[
    2, // Total number of elements in 'shape'
    2, // First element of 'shape'
    2, // Second element of 'shape'
    4, // Total number of elements in 'data'
    1, // First element of 'data'
    2, // Second element of 'data'
    3, // Third element of 'data'
    4  // Fourth element of 'data'
]

The discrepancy suggests an issue with how the struct is being serialized upon return.

What version/commit are you on? Current Version/Commit: Branch cairo-1-input-args From this PR: https://github.com/lambdaclass/cairo-vm/pull/1551

fmoletta commented 9 months ago

Hello, we can definitely fetch the arrays from memory when fetching the return values to show the full arrays instead of their start and end addresses, but I find the expected format a bit confusing. I would suggest serializing it as [2 2] [1 2 3 4] instead to match the convention used for input args and we don't mix up the amount of elements on the array with the actual array elements

raphaelDkhn commented 9 months ago

Hello, we can definitely fetch the arrays from memory when fetching the return values to show the full arrays instead of their start and end addresses, but I find the expected format a bit confusing. I would suggest serializing it as [2 2] [1 2 3 4] instead to match the convention used for input args and we don't mix up the amount of elements on the array with the actual array elements

I was following the same serialization than Cairo (if I'm not mistaken). But your suggestion sounds good as well.