Skip to content

Commit

Permalink
Allow multiple hints for the same pc (#193)
Browse files Browse the repository at this point in the history
* add multiple hints for the same pc

* modify RunHint and hinter maps

* fix linting errors
  • Loading branch information
cicr99 authored Feb 1, 2024
1 parent 2c7509b commit 88587ae
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 28 deletions.
17 changes: 10 additions & 7 deletions pkg/hintrunner/hintrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ type HintRunner struct {
// Execution context required by certain hints such as dictionaires
context h.HintRunnerContext
// A mapping from program counter to hint implementation
hints map[uint64]h.Hinter
hints map[uint64][]h.Hinter
}

func NewHintRunner(hints map[uint64]h.Hinter) HintRunner {
func NewHintRunner(hints map[uint64][]h.Hinter) HintRunner {
return HintRunner{
// Context for certain hints that require it. Each manager is
// initialized only when required by the hint
Expand All @@ -30,14 +30,17 @@ func NewHintRunner(hints map[uint64]h.Hinter) HintRunner {
}

func (hr *HintRunner) RunHint(vm *VM.VirtualMachine) error {
hint := hr.hints[vm.Context.Pc.Offset]
if hint == nil {
hints := hr.hints[vm.Context.Pc.Offset]
if len(hints) == 0 {
return nil
}

err := hint.Execute(vm, &hr.context)
if err != nil {
return fmt.Errorf("execute hint %s: %v", hint, err)
for _, hint := range hints {
err := hint.Execute(vm, &hr.context)
if err != nil {
return fmt.Errorf("execute hint %s: %v", hint, err)
}
}

return nil
}
8 changes: 4 additions & 4 deletions pkg/hintrunner/hintrunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func TestExistingHint(t *testing.T) {
var ap hinter.ApCellRef = 5
allocHint := core.AllocSegment{Dst: ap}

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

vm.Context.Pc = memory.MemoryAddress{
Expand All @@ -42,8 +42,8 @@ func TestNoHint(t *testing.T) {
var ap hinter.ApCellRef = 5
allocHint := core.AllocSegment{Dst: ap}

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

vm.Context.Pc = memory.MemoryAddress{
Expand Down
20 changes: 8 additions & 12 deletions pkg/hintrunner/zero/zerohint.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,22 @@ import (
zero "github.com/NethermindEth/cairo-vm-go/pkg/parsers/zero"
)

func GetZeroHints(cairoZeroJson *zero.ZeroProgram) (map[uint64]hinter.Hinter, error) {
hints := make(map[uint64]hinter.Hinter)
func GetZeroHints(cairoZeroJson *zero.ZeroProgram) (map[uint64][]hinter.Hinter, error) {
hints := make(map[uint64][]hinter.Hinter)
for counter, rawHints := range cairoZeroJson.Hints {
pc, err := strconv.ParseUint(counter, 10, 64)
if err != nil {
return nil, err
}

// TODO: Check if it is possible to have more than one hint
if len(rawHints) != 1 {
return nil, fmt.Errorf("expected only 1 hint but got %d", len(rawHints))
}
rawHint := rawHints[0]
for _, rawHint := range rawHints {
hint, err := GetHintFromCode(cairoZeroJson, rawHint, pc)
if err != nil {
return nil, err
}

hint, err := GetHintFromCode(cairoZeroJson, rawHint, pc)
if err != nil {
return nil, err
hints[pc] = append(hints[pc], hint)
}

hints[pc] = hint
}

return hints, nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/runners/zero/zero.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type ZeroRunner struct {
}

// Creates a new Runner of a Cairo Zero program
func NewRunner(program *Program, hints map[uint64]hinter.Hinter, proofmode bool, maxsteps uint64) (ZeroRunner, error) {
func NewRunner(program *Program, hints map[uint64][]hinter.Hinter, proofmode bool, maxsteps uint64) (ZeroRunner, error) {
hintrunner := hintrunner.NewHintRunner(hints)

return ZeroRunner{
Expand Down
8 changes: 4 additions & 4 deletions pkg/runners/zero/zero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestSimpleProgram(t *testing.T) {
ret;
`)

hints := make(map[uint64]hinter.Hinter)
hints := make(map[uint64][]hinter.Hinter)
runner, err := NewRunner(program, hints, false, math.MaxUint64)
require.NoError(t, err)

Expand Down Expand Up @@ -73,7 +73,7 @@ func TestStepLimitExceeded(t *testing.T) {
ret;
`)

hints := make(map[uint64]hinter.Hinter)
hints := make(map[uint64][]hinter.Hinter)
runner, err := NewRunner(program, hints, false, 3)
require.NoError(t, err)

Expand Down Expand Up @@ -132,7 +132,7 @@ func TestStepLimitExceededProofMode(t *testing.T) {
t.Logf("Using maxstep: %d\n", maxstep)
// when maxstep = 6, it fails executing the extra step required by proof mode
// when maxstep = 7, it fails trying to get the trace to be a power of 2
hints := make(map[uint64]hinter.Hinter)
hints := make(map[uint64][]hinter.Hinter)
runner, err := NewRunner(program, hints, true, uint64(maxstep))
require.NoError(t, err)

Expand Down Expand Up @@ -367,7 +367,7 @@ func TestEcOpBuiltin(t *testing.T) {
func createRunner(code string, builtins ...sn.Builtin) ZeroRunner {
program := createProgramWithBuiltins(code, builtins...)

hints := make(map[uint64]hinter.Hinter)
hints := make(map[uint64][]hinter.Hinter)
runner, err := NewRunner(program, hints, false, math.MaxUint64)
if err != nil {
panic(err)
Expand Down

0 comments on commit 88587ae

Please sign in to comment.