Skip to content

Commit

Permalink
Add Ids.GetConst + SetupConstantsForTest (#238)
Browse files Browse the repository at this point in the history
* Add IdsManager.GetConst

* Integrate into logic

* Add utils to help with fetching constants

* Add SetupConstantsForTest

* Add comments

* Guard error case

* Fix typo

* Fix util

---------

Co-authored-by: Mariano A. Nicolini <[email protected]>
  • Loading branch information
fmoletta and entropidelic authored Sep 18, 2023
1 parent 975ffcf commit 60d7b72
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pkg/hints/hint_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func (p *CairoVmHintProcessor) CompileHint(hintParams *parser.HintParams, refere
name = split[len(split)-1]
references[name] = ParseHintReference(referenceManager.References[n])
}
ids := NewIdsManager(references, hintParams.FlowTrackingData.APTracking)
ids := NewIdsManager(references, hintParams.FlowTrackingData.APTracking, hintParams.AccessibleScopes)
return HintData{Ids: ids, Code: hintParams.Code}, nil
}

Expand Down
28 changes: 23 additions & 5 deletions pkg/hints/hint_utils/ids_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ import (
// Identifier Manager
// Provides methods that allow hints to interact with cairo variables given their identifier name
type IdsManager struct {
References map[string]HintReference
HintApTracking parser.ApTrackingData
References map[string]HintReference
HintApTracking parser.ApTrackingData
AccessibleScopes []string
}

func ErrIdsManager(err error) error {
Expand All @@ -24,13 +25,30 @@ func ErrUnknownIdentifier(name string) error {
return ErrIdsManager(errors.Errorf("Unknow identifier %s", name))
}

func NewIdsManager(references map[string]HintReference, hintApTracking parser.ApTrackingData) IdsManager {
func NewIdsManager(references map[string]HintReference, hintApTracking parser.ApTrackingData, accessibleScopes []string) IdsManager {
return IdsManager{
References: references,
HintApTracking: hintApTracking,
References: references,
HintApTracking: hintApTracking,
AccessibleScopes: accessibleScopes,
}
}

// Fetches a constant used by the hint
// Searches inner modules first for name-matching constants
func (ids *IdsManager) GetConst(name string, constants *map[string]lambdaworks.Felt) (lambdaworks.Felt, error) {
// Hints should always have accessible scopes
if len(ids.AccessibleScopes) != 0 {
// Accessible scopes are listed from outer to inner
for i := len(ids.AccessibleScopes) - 1; i >= 0; i-- {
constant, ok := (*constants)[ids.AccessibleScopes[i]+"."+name]
if ok {
return constant, nil
}
}
}
return lambdaworks.FeltZero(), errors.Errorf("Missing constant %s", name)
}

// Inserts value into memory given its identifier name
func (ids *IdsManager) Insert(name string, value *MaybeRelocatable, vm *VirtualMachine) error {

Expand Down
52 changes: 52 additions & 0 deletions pkg/hints/hint_utils/ids_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,55 @@ func TestIdsManagerGetStructFieldTest(t *testing.T) {
t.Errorf("IdsManager.GetStructFieldFelt returned wrong values")
}
}

func TestIdsManagerGetConst(t *testing.T) {
ids := IdsManager{
AccessibleScopes: []string{
"starkware.cairo.common.math",
"starkware.cairo.common.math.assert_250_bit",
},
}
upperBound := lambdaworks.FeltFromUint64(250)
constants := map[string]lambdaworks.Felt{
"starkware.cairo.common.math.assert_250_bit.UPPER_BOUND": upperBound,
}
constant, err := ids.GetConst("UPPER_BOUND", &constants)
if err != nil || constant != upperBound {
t.Errorf("IdsManager.GetConst returned wrong/no constant")
}
}

func TestIdsManagerGetConstPrioritizeInnerModule(t *testing.T) {
ids := IdsManager{
AccessibleScopes: []string{
"starkware.cairo.common.math",
"starkware.cairo.common.math.assert_250_bit",
},
}
upperBound := lambdaworks.FeltFromUint64(250)
constants := map[string]lambdaworks.Felt{
"starkware.cairo.common.math.assert_250_bit.UPPER_BOUND": upperBound,
"starkware.cairo.common.math.UPPER_BOUND": lambdaworks.FeltZero(),
}
constant, err := ids.GetConst("UPPER_BOUND", &constants)
if err != nil || constant != upperBound {
t.Errorf("IdsManager.GetConst returned wrong/no constant")
}
}

func TestIdsManagerGetConstNoMConst(t *testing.T) {
ids := IdsManager{
AccessibleScopes: []string{
"starkware.cairo.common.math",
"starkware.cairo.common.math.assert_250_bit",
},
}
lowerBound := lambdaworks.FeltFromUint64(250)
constants := map[string]lambdaworks.Felt{
"starkware.cairo.common.math.assert_250_bit.LOWER_BOUND": lowerBound,
}
_, err := ids.GetConst("UPPER_BOUND", &constants)
if err == nil {
t.Errorf("IdsManager.GetConst should have failed")
}
}
14 changes: 13 additions & 1 deletion pkg/hints/hint_utils/testing_utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hint_utils

import (
"github.com/lambdaclass/cairo-vm.go/pkg/lambdaworks"
"github.com/lambdaclass/cairo-vm.go/pkg/parser"
. "github.com/lambdaclass/cairo-vm.go/pkg/vm"
"github.com/lambdaclass/cairo-vm.go/pkg/vm/memory"
Expand All @@ -17,7 +18,7 @@ import (
// All references will be FP-based, so please don't update the value of FP after calling this function,
// and make sure that the memory at fp's segment is clear from its current offset onwards
func SetupIdsForTest(ids map[string][]*memory.MaybeRelocatable, vm *VirtualMachine) IdsManager {
manager := NewIdsManager(make(map[string]HintReference), parser.ApTrackingData{})
manager := NewIdsManager(make(map[string]HintReference), parser.ApTrackingData{}, []string{})
base_addr := vm.RunContext.Fp
current_offset := 0
for name, elems := range ids {
Expand All @@ -43,3 +44,14 @@ func SetupIdsForTest(ids map[string][]*memory.MaybeRelocatable, vm *VirtualMachi
}
return manager
}

// Returns a constants map accoring to the new_constants map received
// Adds a path to each constant and a matching path to the hint's accessible scopes
func SetupConstantsForTest(new_constants map[string]lambdaworks.Felt, ids *IdsManager) map[string]lambdaworks.Felt {
constants := make(map[string]lambdaworks.Felt)
ids.AccessibleScopes = append(ids.AccessibleScopes, "path")
for name, constant := range new_constants {
constants["path."+name] = constant
}
return constants
}
21 changes: 21 additions & 0 deletions pkg/hints/hint_utils/testing_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,24 @@ func TestSetupIdsForTestStructWithGap(t *testing.T) {
t.Error("Failed to insert ids")
}
}

func TestSetupConstantsForTest(t *testing.T) {
constA := FeltOne()
constB := FeltZero()
IdsManager := IdsManager{}
constants := SetupConstantsForTest(map[string]Felt{
"A": constA,
"B": constB,
},
&IdsManager,
)
// Check that we can fetch the constants
a, err := IdsManager.GetConst("A", &constants)
if err != nil || a != constA {
t.Error("SetupConstantsForTest wrong/no A")
}
b, err := IdsManager.GetConst("B", &constants)
if err != nil || b != constB {
t.Error("SetupConstantsForTest wrong/no B")
}
}

0 comments on commit 60d7b72

Please sign in to comment.