kkrt-labs / cairo-vm-ts

A typescript implementation of the Cairo VM
Apache License 2.0
20 stars 13 forks source link

research: why does the relocated memory starts at 1? #60

Closed zmalatrax closed 5 months ago

zmalatrax commented 5 months ago

Need to investigate why the relocated memory starts at address 1 rather than 0.

TAdev0 commented 5 months ago

https://docs.cairo-lang.org/how_cairo_works/segments.html

In the doc, we see in the segment relocation table that it indeed starts by 1. It might be just a convention. We have a bug in the Nethermind Cairo Vm in Go related to segments offsets calculation, will try to investigate on this as well

TAdev0 commented 5 months ago

Ok i think i found the reason: I ran the example in the link provided below.

Here is the memory after running the program:

Addr  Value
-----------
⋮
0:0   290341444919459839
0:1   1
0:2   1226245742482522112
0:3   4
0:4   74168662805676031
0:5   0
0:6   5191102247248822272
0:7   5189976364521848832
0:8   12
0:9   4612389708016484351
0:10  5198983563776458752
0:11  1
0:12  2345108766317314046
⋮
1:0   2:0
1:1   3:0
1:2   4:0
1:3   2:0
1:4   12
1:5   2:1
⋮
2:0   12

and with printing relocates:

Addr  Value
-----------
⋮
1     290341444919459839
2     1
3     1226245742482522112
4     4
5     74168662805676031
6     0
7     5191102247248822272
8     5189976364521848832
9     12
10    4612389708016484351
11    5198983563776458752
12    1
13    2345108766317314046
14    20
15    21
16    21
17    20
18    12
19    21
20    12

Segment relocation table:
0     1
1     14
2     20
3     21
4     21

The line 1:0 2:0 (address, value) corresponds to 14 20 (address, value) with relocates.

This means that the value 2:0 corresponds to the relocation of segment, not the value contained at slot 0 in this segment.

Overall:

1:0   2:0
1:1   3:0
1:2   4:0
1:3   2:0

represents actually 4 contiguous value in memory that represent relocations and not value of the first used memory cell of the segmenet, this is why it corresponds to :

14    20
15    21
16    21
17    20

So I guess it is actually needed to consider , after relocation, that each segment should start by 1, so that the 0 index corresponds to the relocation segment value

ClementWalter commented 5 months ago

I don’t think that is exact. It just means that you put during the run alloc() in the execution segment, but actually never filled these new segments. Hence all the values are relocated to the same final address

TAdev0 commented 5 months ago

can you expand a bit more? i'm not sure to fully understand what you mean

TAdev0 commented 5 months ago

oh yeah now i see. Ok yeah, now indeed i feel like my explanation is wrong. It would work perfectly well with a 0-based relocated memory

ilyalesokhin-starkware commented 5 months ago

The relocated memory starts at address 1 rather than 0 because we wanted the null pointer to be invalid.

https://github.com/starkware-libs/starkex-contracts/blob/aecf37f2278b2df233edd13b686d0aa9462ada02/evm-verifier/solidity/contracts/cpu/CpuPublicInputOffsetsBase.sol#L23

ilyalesokhin-starkware commented 5 months ago

There is also a constraint that enforces the first memory address is 1. https://github.com/starkware-libs/starkex-contracts/blob/aecf37f2278b2df233edd13b686d0aa9462ada02/evm-verifier/solidity/contracts/cpu/layout2/CpuConstraintPoly.sol#L1978