From 65b8ce6d632b4b4306f950b0f2a318a3dfdaf346 Mon Sep 17 00:00:00 2001 From: toni-calvin Date: Tue, 19 Sep 2023 13:46:23 +0200 Subject: [PATCH] add continue loop hint --- pkg/hints/hint_processor.go | 2 + pkg/hints/memcpy_hints_test.go | 33 ---------- pkg/hints/memset_hint_codes.go | 1 + pkg/hints/memset_hints_test.go | 107 +++++++++++++++++++++++++++++++++ pkg/types/exec_scope_utils.go | 7 +++ 5 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 pkg/types/exec_scope_utils.go diff --git a/pkg/hints/hint_processor.go b/pkg/hints/hint_processor.go index 63c78a8a..d5950744 100644 --- a/pkg/hints/hint_processor.go +++ b/pkg/hints/hint_processor.go @@ -73,6 +73,8 @@ func (p *CairoVmHintProcessor) ExecuteHint(vm *vm.VirtualMachine, hintData *any, return memset_enter_scope(data.Ids, vm, execScopes) case MEMCPY_CONTINUE_COPYING: return memset_step_loop(data.Ids, vm, execScopes, "continue_copying") + case MEMSET_CONTINUE_LOOP: + return memset_step_loop(data.Ids, vm, execScopes, "continue_loop") default: return errors.Errorf("Unknown Hint: %s", data.Code) } diff --git a/pkg/hints/memcpy_hints_test.go b/pkg/hints/memcpy_hints_test.go index 941216f3..eb5d159d 100644 --- a/pkg/hints/memcpy_hints_test.go +++ b/pkg/hints/memcpy_hints_test.go @@ -241,36 +241,3 @@ func TestMemcpyContinueCopyingInsertError(t *testing.T) { t.Errorf("TestMemcpyContinueCopyingInsertError should fail with error %s", expected) } } - -// func TestMemsetContinueCopyingValidEqual5Hint(t *testing.T) { -// vm := NewVirtualMachine() -// vm.RunContext.Fp = NewRelocatable(1, 0) -// vm.Segments.Memory.Data[NewRelocatable(1, 2)] = *NewMaybeRelocatableFelt(FeltFromUint64(5)) -// idsManager := SetupIdsForTest( -// map[string][]*MaybeRelocatable{ -// "continue_copying": nil, -// }, -// vm, -// ) -// hintProcessor := CairoVmHintProcessor{} -// hintData := any(HintData{ -// Ids: idsManager, -// Code: MEMCPY_CONTINUE_COPYING, -// }) - -// executionScopes := NewExecutionScopes() -// scope := make(map[string]interface{}) -// scope["n"] = FeltFromUint64(5) -// executionScopes.EnterScope(scope) -// err := hintProcessor.ExecuteHint(vm, &hintData, nil, executionScopes) -// if err != nil { -// t.Errorf("TestMemsetContinueCopyingValidEqual5Hint failed with error %s", err) -// } -// val, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 0)) -// if err != nil { -// t.Errorf("TestMemsetContinueCopyingValidEqual5Hint failed with error %s", err) -// } -// if val != FeltZero() { -// t.Errorf("TestMemsetContinueCopyingValidEqual5Hint failed, expected %d, got: %d", FeltZero(), val) -// } -// } diff --git a/pkg/hints/memset_hint_codes.go b/pkg/hints/memset_hint_codes.go index 98489424..270f621c 100644 --- a/pkg/hints/memset_hint_codes.go +++ b/pkg/hints/memset_hint_codes.go @@ -1,3 +1,4 @@ package hints const MEMSET_ENTER_SCOPE = "vm_enter_scope({'n': ids.n})" +const MEMSET_CONTINUE_LOOP = "n -= 1 ids.continue_loop = 1 if n > 0 else 0" diff --git a/pkg/hints/memset_hints_test.go b/pkg/hints/memset_hints_test.go index 5be53d8c..7e6e585e 100644 --- a/pkg/hints/memset_hints_test.go +++ b/pkg/hints/memset_hints_test.go @@ -74,3 +74,110 @@ func TestMemsetEnterScopeInvalid(t *testing.T) { } } + +func TestMemsetContinueLoopValidEqual1Hint(t *testing.T) { + vm := NewVirtualMachine() + vm.RunContext.Fp = NewRelocatable(1, 0) + vm.Segments = AddNSegments(vm.Segments, 2) + executionScopes := NewExecutionScopesWithInitValue("n", FeltFromUint64(1)) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "continue_loop": {NewMaybeRelocatableFeltFromUint64(0)}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: MEMSET_CONTINUE_LOOP, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, executionScopes) + if err != nil { + t.Errorf("failed with error %s", err) + } + val, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 0)) + if err != nil { + t.Errorf("failed with error %s", err) + } + if val != FeltZero() { + t.Errorf("failed, expected %d, got: %d", FeltZero(), val) + } +} + +func TestMemsetContinueLoopValidEqual5Hint(t *testing.T) { + vm := NewVirtualMachine() + vm.RunContext.Fp = NewRelocatable(1, 0) + vm.Segments = AddNSegments(vm.Segments, 2) + executionScopes := NewExecutionScopesWithInitValue("n", FeltFromUint64(5)) + + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "continue_loop": {NewMaybeRelocatableFeltFromUint64(1)}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: MEMSET_CONTINUE_LOOP, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, executionScopes) + if err != nil { + t.Errorf("failed with error %s", err) + } + val, err := vm.Segments.Memory.GetFelt(NewRelocatable(1, 0)) + if err != nil { + t.Errorf("failed with error %s", err) + } + if val != FeltOne() { + t.Errorf("failed, expected %d, got: %d", FeltOne(), val) + } +} + +func TestMemsetContinueLoopVarNotInScope(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments.AddSegment() + executionScopes := NewExecutionScopes() + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "continue_loop": {NewMaybeRelocatableFeltFromUint64(1)}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: MEMSET_CONTINUE_LOOP, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, executionScopes) + if err.Error() != ErrVariableNotInScope("n").Error() { + t.Errorf("should fail with error %s", ErrVariableNotInScope("n")) + } +} + +func TestMemsetContinueLoopInsertError(t *testing.T) { + vm := NewVirtualMachine() + vm.Segments = AddNSegments(vm.Segments, 2) + executionScopes := NewExecutionScopesWithInitValue("n", FeltOne()) + idsManager := SetupIdsForTest( + map[string][]*MaybeRelocatable{ + "continue_loop": {NewMaybeRelocatableFelt(FeltFromUint64(5))}, + }, + vm, + ) + hintProcessor := CairoVmHintProcessor{} + hintData := any(HintData{ + Ids: idsManager, + Code: MEMSET_CONTINUE_LOOP, + }) + + err := hintProcessor.ExecuteHint(vm, &hintData, nil, executionScopes) + expected := ErrMemoryWriteOnce(NewRelocatable(0, 0), *NewMaybeRelocatableFeltFromUint64(5), *NewMaybeRelocatableFeltFromUint64(0)) + if err.Error() != expected.Error() { + t.Errorf("should fail with error %s", expected) + } +} diff --git a/pkg/types/exec_scope_utils.go b/pkg/types/exec_scope_utils.go new file mode 100644 index 00000000..4a6cab69 --- /dev/null +++ b/pkg/types/exec_scope_utils.go @@ -0,0 +1,7 @@ +package types + +func NewExecutionScopesWithInitValue(key string, val interface{}) *ExecutionScopes { + scopes := NewExecutionScopes() + scopes.EnterScope(map[string]interface{}{key: val}) + return scopes +}