Skip to content

Commit

Permalink
Missing dict functionalities (#680)
Browse files Browse the repository at this point in the history
* Fixes for the generation of entry code, fixes of hints parsing

* Add modifications to the runner

* Add fixes for the entrycode generation

* Refactor main CLI, offset the hints indexes by entry code size, load arguments and initial gas to the memory

* Add available gas and user args (#677)

* Add parsing logic for input user args

* Add flags for available gas, input user args, writing args to memory

* Fix unit tests for user arguments parsing

* Lint the PR

* Add user args to hint context

* Refactor the code

* Fix unconditional append of ExternalWriteArgsToMemory, bug fixes in integration tests

* Add fixes of the call size calculation and include ExternalWriteArgsToMemory hint when gas present

* Add layouts for integration tests

* Add error handling

* Fixes in entry code generation

* Address changes mentioned in a discussion

* Add comment regarding writing to memory in a hint for the future reference in the integration tests with args

* Changes in calculations of the initial PC offset, CALL opcode offset incremented by mainFuncOffset, writing user args to the AP in the hint

* Turn back VM config to private field

* Add error handling on assign of `userArgs` to the initial scope

* Lint project

* Bump go version from 1.20 -> 1.21 (#678)

* Bump go version from 1.20 -> 1.21

* Update golangci-lint

* Simplify the Makefile

* Correction in the makefile

* Fix the integration tests

* Fixes in the runner

* Fixes in the runner

* Fix the unit tests, uncomment pythonVm execution in integration tests, code cleanups

* Add writing tokens gas cost to memory

* Proper builtins initialization for cairo mode

* Address comments in the PR

* Fix bugs regarding dicts

* Remove prints

* Fixes of the last tests for the dicts

* Add dict_non_squashed dir to the integration tests

* Address all the comments
  • Loading branch information
MaksymMalicki authored Jan 14, 2025
1 parent ef6735c commit fae330d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 15 deletions.
1 change: 1 addition & 0 deletions integration_tests/cairo_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func TestCairoFiles(t *testing.T) {
{"./cairo_zero_file_tests/", true},
{"./builtin_tests/", true},
// {"./cairo_1_programs/", false},
// {"./cairo_1_programs/dict_non_squashed", false},
}

// filter is for debugging purposes
Expand Down
25 changes: 17 additions & 8 deletions pkg/hintrunner/core/hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,8 @@ func (hint *Felt252DictEntryInit) Execute(vm *VM.VirtualMachine, ctx *hinter.Hin

prevValue, err := ctx.DictionaryManager.At(dictPtr, key)
if err != nil {
return fmt.Errorf("get dictionary entry: %w", err)
mv := mem.MemoryValueFromFieldElement(&utils.FeltZero)
prevValue = &mv
}
if prevValue == nil {
mv := mem.EmptyMemoryValueAsFelt()
Expand Down Expand Up @@ -1234,10 +1235,10 @@ func (hint *InitSquashData) String() string {
}

func (hint *InitSquashData) Execute(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
// todo(rodro): Don't know if it could be called multiple times, or
err := hinter.InitializeSquashedDictionaryManager(ctx)
if err != nil {
return err
ctx.SquashedDictionaryManager = hinter.SquashedDictionaryManager{}
_ = hinter.InitializeSquashedDictionaryManager(ctx)
}

dictAccessPtr, err := hinter.ResolveAsAddress(vm, hint.DictAccesses)
Expand Down Expand Up @@ -1272,7 +1273,7 @@ func (hint *InitSquashData) Execute(vm *VM.VirtualMachine, ctx *hinter.HintRunne

// sort the keys in descending order
sort.Slice(ctx.SquashedDictionaryManager.Keys, func(i, j int) bool {
return ctx.SquashedDictionaryManager.Keys[i].Cmp(&ctx.SquashedDictionaryManager.Keys[j]) < 0
return ctx.SquashedDictionaryManager.Keys[i].Cmp(&ctx.SquashedDictionaryManager.Keys[j]) > 0
})

// if the first key is bigger than 2^128, signal it
Expand Down Expand Up @@ -1401,11 +1402,15 @@ func (hint *ShouldContinueSquashLoop) Execute(vm *VM.VirtualMachine, ctx *hinter
}

var shouldContinueLoop f.Element
if lastIndices, err := ctx.SquashedDictionaryManager.LastIndices(); err == nil && len(lastIndices) <= 1 {
shouldContinueLoop.SetOne()
} else if err != nil {
lastIndices, err := ctx.SquashedDictionaryManager.LastIndices()
if err != nil {
return fmt.Errorf("get last indices: %w", err)
}
if len(lastIndices) > 1 {
shouldContinueLoop.SetOne()
} else {
shouldContinueLoop.SetZero()
}

mv := mem.MemoryValueFromFieldElement(&shouldContinueLoop)
return vm.Memory.WriteToAddress(&shouldContinuePtr, &mv)
Expand All @@ -1425,11 +1430,15 @@ func (hint *GetNextDictKey) Execute(vm *VM.VirtualMachine, ctx *hinter.HintRunne
return fmt.Errorf("get next key address: %w", err)
}

nextKey, err := ctx.SquashedDictionaryManager.PopKey()
_, err = ctx.SquashedDictionaryManager.PopKey()
if err != nil {
return fmt.Errorf("pop key: %w", err)
}

nextKey, err := ctx.SquashedDictionaryManager.LastKey()
if err != nil {
return fmt.Errorf("get last key: %w", err)
}
mv := mem.MemoryValueFromFieldElement(&nextKey)
return vm.Memory.WriteToAddress(&nextKeyAddr, &mv)
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/runner/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func gasInitialization(memory *mem.Memory) error {
if err != nil {
return err
}

preCostTokenTypes := []TokenGasCost{PedersenToken, BitwiseToken, EcOpToken, PoseidonToken, AddModToken, MulModToken}
// The order of the tokens is relevant, source: https://github.com/starkware-libs/cairo/blob/f6aaaa306804257bfc15d65b5ab6b90e141b54ec/crates/cairo-lang-sierra/src/extensions/modules/gas.rs#L194
preCostTokenTypes := []TokenGasCost{PedersenToken, PoseidonToken, BitwiseToken, EcOpToken, AddModToken, MulModToken}

for _, token := range preCostTokenTypes {
cost, err := getTokenGasCost(token)
Expand Down
42 changes: 37 additions & 5 deletions pkg/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,13 +541,47 @@ func GetEntryCodeInstructions(function starknet.EntryPointByFunction, finalizeFo
}

ctx := &InlineCasmContext{}

gotSegmentArena := false
for _, builtin := range function.Builtins {
if builtin == builtins.SegmentArenaType {
gotSegmentArena = true
}
}

hints := make(map[uint64][]hinter.Hinter)

if gotSegmentArena {
hints[uint64(ctx.currentCodeOffset)] = []hinter.Hinter{
&core.AllocSegment{
Dst: hinter.ApCellRef(0),
},
&core.AllocSegment{
Dst: hinter.ApCellRef(1),
},
}
ctx.AddInlineCASM(
"[ap+2] = 0, ap++;",
)
ctx.AddInlineCASM(
"[ap] = [[ap-1]], ap++;",
)
ctx.AddInlineCASM(
`
[ap] = [[ap-2]+1], ap++;
[ap-1] = [[ap-3]+2];
`,
)
apOffset += 3
}

paramsSize := 0
for _, param := range paramTypes {
paramsSize += param.Size
}
apOffset += paramsSize
usedArgs := 0
var hints map[uint64][]hinter.Hinter

for _, builtin := range function.Builtins {
if offset, isBuiltin := builtinsOffsetsMap[builtin]; isBuiltin {
ctx.AddInlineCASM(
Expand All @@ -561,10 +595,8 @@ func GetEntryCodeInstructions(function starknet.EntryPointByFunction, finalizeFo
)
apOffset += 1
} else if builtin == builtins.GasBuiltinType {
hints = map[uint64][]hinter.Hinter{
uint64(ctx.currentCodeOffset): {
&core.ExternalWriteArgsToMemory{},
},
hints[uint64(ctx.currentCodeOffset)] = []hinter.Hinter{
&core.ExternalWriteArgsToMemory{},
}
ctx.AddInlineCASM("ap += 1;")
apOffset += 1
Expand Down

0 comments on commit fae330d

Please sign in to comment.