Skip to content

Commit

Permalink
Code refactoring, add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
MaksymMalicki committed Jan 17, 2025
1 parent fea8144 commit bf3a585
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 25 deletions.
7 changes: 4 additions & 3 deletions integration_tests/cairo_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,12 @@ func TestCairoFiles(t *testing.T) {
{"./cairo_zero_hint_tests/", true},
{"./cairo_zero_file_tests/", true},
{"./builtin_tests/", true},
{"./cairo_1_programs/", false},
{"./cairo_1_programs/dict_non_squashed", false},
{"./cairo_1_programs/with_input", false},
// {"./cairo_1_programs/", false},
// {"./cairo_1_programs/dict_non_squashed", false},
// {"./cairo_1_programs/with_input", false},
}

// inputArgsMap is used to provide input arguments to the tests that require them. Whenever the args are needed for the new files, they can simply be added here.
inputArgsMap := map[string]string{
"cairo_1_programs/with_input/array_input_sum__small.cairo": "2 [111 222 333] 1 [444 555 666 777]",
"cairo_1_programs/with_input/array_length__small.cairo": "[1 2 3 4 5 6] [7 8 9 10]",
Expand Down
9 changes: 9 additions & 0 deletions pkg/hintrunner/core/hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,8 @@ func (hint *ExternalWriteArgsToMemory) Execute(vm *VM.VirtualMachine, ctx *hinte
if err != nil {
return fmt.Errorf("get user args: %v", err)
}
// The apOffset is the AP correction, which represents the memory slots taken up by the values created by the entry code instructions.
// It is calculated in the `getNewHintRunnerContext()` method.
apOffset, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "apOffset")
if err != nil {
return fmt.Errorf("get ap offset: %v", err)
Expand All @@ -1955,6 +1957,10 @@ func (hint *ExternalWriteArgsToMemory) Execute(vm *VM.VirtualMachine, ctx *hinte
}
apOffset++
} else if arg.Array != nil {
// The array is stored in memory as follows:
// Each array gets assigned a new segment (the pointer is stored in the arrayBase).
// arrayBase and arrayEnd pointers are written to the Execution Segment consecutively.
// Then, the array elements are written to the newly created array segment.
arrayBase := vm.Memory.AllocateEmptySegment()
mv := mem.MemoryValueFromMemoryAddress(&arrayBase)
err := vm.Memory.Write(1, apOffset, &mv)
Expand Down Expand Up @@ -1989,6 +1995,9 @@ func (hint *ExternalWriteGasToMemory) String() string {
}

func (hint *ExternalWriteGasToMemory) Execute(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
// ExternalWriteGasToMemory is a separate hint, that writes the gas value to the memory.
// The gas value is written to the memory cell reserved by the instruction generated in entry code, which is dependent on the ordering of builtins list.
// Therefore the writing of the gas value to the memory is done in a separate hint.
gas, err := hinter.GetVariableAs[uint64](&ctx.ScopeManager, "gas")
if err != nil {
return fmt.Errorf("get gas: %v", err)
Expand Down
14 changes: 2 additions & 12 deletions pkg/hintrunner/hintrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

h "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
"github.com/NethermindEth/cairo-vm-go/pkg/parsers/starknet"
VM "github.com/NethermindEth/cairo-vm-go/pkg/vm"
)

Expand All @@ -15,20 +14,11 @@ type HintRunner struct {
hints map[uint64][]h.Hinter
}

func NewHintRunner(hints map[uint64][]h.Hinter, userArgs []starknet.CairoFuncArgs, writeApOffset uint64, availableGas uint64) HintRunner {
context := *h.InitializeDefaultContext()
err := context.ScopeManager.AssignVariables(map[string]any{
"userArgs": userArgs,
"apOffset": writeApOffset,
"gas": availableGas,
})
if err != nil {
panic(fmt.Sprintf("assign variables: %v", err))
}
func NewHintRunner(hints map[uint64][]h.Hinter, newHintRunnerContext *h.HintRunnerContext) HintRunner {
return HintRunner{
// Context for certain hints that require it. Each manager is
// initialized only when required by the hint
context: context,
context: *newHintRunnerContext,
hints: hints,
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/hintrunner/hintrunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestExistingHint(t *testing.T) {

hr := NewHintRunner(map[uint64][]hinter.Hinter{
10: {&allocHint},
}, nil, 0, 0)
}, nil)

vm.Context.Pc = memory.MemoryAddress{
SegmentIndex: 0,
Expand All @@ -44,7 +44,7 @@ func TestNoHint(t *testing.T) {

hr := NewHintRunner(map[uint64][]hinter.Hinter{
10: {&allocHint},
}, nil, 0, 0)
}, nil)

vm.Context.Pc = memory.MemoryAddress{
SegmentIndex: 0,
Expand Down
42 changes: 35 additions & 7 deletions pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,8 @@ func NewRunner(program *Program, hints map[uint64][]hinter.Hinter, runnerMode Ru
if err != nil {
return Runner{}, err
}
writeApOffset := uint64(len(program.Builtins))
for _, builtin := range program.Builtins {
if builtin == builtins.SegmentArenaType {
writeApOffset += 3
}
}
hintrunner := hintrunner.NewHintRunner(hints, userArgs, writeApOffset, availableGas)
newHintRunnerContext := getNewHintRunnerContext(program, userArgs, availableGas)
hintrunner := hintrunner.NewHintRunner(hints, &newHintRunnerContext)
return Runner{
program: program,
runnerMode: runnerMode,
Expand All @@ -65,6 +60,37 @@ func NewRunner(program *Program, hints map[uint64][]hinter.Hinter, runnerMode Ru
}, nil
}

func getNewHintRunnerContext(program *Program, userArgs []starknet.CairoFuncArgs, availableGas uint64) hinter.HintRunnerContext {
// The writeApOffset is the offset where the user arguments will be written. It is added to the current AP in the ExternalWriteArgsToMemory hint.
// The writeApOffset is significant for Cairo programs, because of the prepended Entry Code instructions.
// In the entry code instructions the builtins bases (excluding gas, segment arena and output) are written to the memory,
// thus the writeApOffset should be increased by the number of builtins.
// In the entry code the instructions for programs utilizing the SegmentArena are also prepended. The SegmentArena is a builtin that requires 4 cells:
// * segment_arena_ptr
// * info_segment_ptr
// * 0
// * segment_arena_ptr + 3
// But the builtin itself shouldn't be included in len(builtins), therefore the writeApOffset should be increased by 3.
writeApOffset := uint64(len(program.Builtins))
for _, builtin := range program.Builtins {
if builtin == builtins.SegmentArenaType {
writeApOffset += 3
}
}

newHintrunnerContext := *hinter.InitializeDefaultContext()
err := newHintrunnerContext.ScopeManager.AssignVariables(map[string]any{
"userArgs": userArgs,
"apOffset": writeApOffset,
"gas": availableGas,
})
// Error handling: this condition should never be true, since the context was initialized above
if err != nil {
panic(fmt.Sprintf("assign variables: %v", err))
}
return newHintrunnerContext
}

func AssembleProgram(cairoProgram *starknet.StarknetProgram, userArgs []starknet.CairoFuncArgs, availableGas uint64) (Program, map[uint64][]hinter.Hinter, []starknet.CairoFuncArgs, error) {
mainFunc, ok := cairoProgram.EntryPointsByFunction["main"]
if !ok {
Expand Down Expand Up @@ -621,12 +647,14 @@ func GetEntryCodeInstructions(function starknet.EntryPointByFunction) ([]*fp.Ele
}
}

// Incrementing the AP for the input args, because their values are written to memory by the VM in the ExternalWriteArgsToMemory hint.
for _, param := range paramTypes {
ctx.AddInlineCASM(
fmt.Sprintf("ap+=%d;", param.Size),
)
}

// The hint can be executed before the first instruction, because the AP correction was calculated based on the input arguments.
if paramsSize > 0 {
hints[uint64(0)] = append(hints[uint64(0)], []hinter.Hinter{
&core.ExternalWriteArgsToMemory{},
Expand Down
1 change: 0 additions & 1 deletion pkg/vm/builtins/builtin_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const (
AddModeType
MulModType
GasBuiltinType
SystemType
)

func Runner(name BuiltinType) memory.BuiltinRunner {
Expand Down

0 comments on commit bf3a585

Please sign in to comment.