Skip to content

Commit

Permalink
Fixes after merge
Browse files Browse the repository at this point in the history
  • Loading branch information
MaksymMalicki committed Oct 22, 2024
1 parent 3091ab5 commit a9800e2
Show file tree
Hide file tree
Showing 9 changed files with 351 additions and 347 deletions.
360 changes: 221 additions & 139 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,164 +102,125 @@ func main() {
},
},
Action: func(ctx *cli.Context) error {
// TODO: move this action's body to a separate function to decrease the
// code nesting significantly.

pathToFile := ctx.Args().Get(0)
if pathToFile == "" {
return fmt.Errorf("path to cairo file not set")
}
cairoVersion, err := cairoversion.GetCairoVersion(pathToFile)
if err != nil {
return fmt.Errorf("cannot get cairo version: %w", err)
}

var hints map[uint64][]hinter.Hinter
var program *runnerzero.Program
if cairoVersion > 0 {
cairoProgram, err := starknet.StarknetProgramFromFile(pathToFile)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
hints, err = core.GetCairoHints(cairoProgram)
if err != nil {
return fmt.Errorf("cannot get hints: %w", err)
}
program, err = runnerzero.LoadCairoProgram(cairoProgram)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
} else {
fmt.Printf("Loading program at %s\n", pathToFile)
zeroProgram, err := zero.ZeroProgramFromFile(pathToFile)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
hints, err = hintrunner.GetZeroHints(zeroProgram)
if err != nil {
return fmt.Errorf("cannot create hints: %w", err)
}
program, err = runnerzero.LoadCairoZeroProgram(zeroProgram)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
}
runnerMode := runnerzero.ExecutionMode
switch {
case proofmode && cairoVersion > 0:
runnerMode = runnerzero.ProofModeCairo1
case proofmode && cairoVersion == 0:
runnerMode = runnerzero.ProofModeCairo0
}
program, err := runner.LoadCairoZeroProgram(zeroProgram)
var program *runner.Program
fmt.Printf("Loading program at %s\n", pathToFile)
zeroProgram, err := zero.ZeroProgramFromFile(pathToFile)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
fmt.Println("Running....")
runner, err := runnerzero.NewRunner(runnerMode, program, hints, proofmode, collectTrace, maxsteps, layoutName)
hints, err = hintrunner.GetZeroHints(zeroProgram)
if err != nil {
return fmt.Errorf("cannot create runner: %w", err)
return fmt.Errorf("cannot create hints: %w", err)
}

// Run executes main(), RunEntryPoint is used to test contract_class-style entry points.
// In theory, calling RunEntryPoint with main's offset should behave identically,
// but these functions are implemented differently in both this and cairo-rs VMs
// and the difference is quite subtle.
if entrypointOffset == 0 {
if err := runner.Run(); err != nil {
return fmt.Errorf("runtime error: %w", err)
}
} else {
if err := runner.RunEntryPoint(entrypointOffset); err != nil {
return fmt.Errorf("runtime error (entrypoint=%d): %w", entrypointOffset, err)
}
program, err = runner.LoadCairoZeroProgram(zeroProgram)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}

runnerMode := runner.ExecutionMode
if proofmode {
if err := runner.EndRun(); err != nil {
return fmt.Errorf("cannot end run: %w", err)
}
if err := runner.FinalizeSegments(); err != nil {
return fmt.Errorf("cannot finalize segments: %w", err)
}
runnerMode = runner.ProofModeCairo0
}

if proofmode || collectTrace {
trace, err := runner.BuildTrace()
if err != nil {
return fmt.Errorf("cannot build trace: %w", err)
}

if traceLocation != "" {
if err := os.WriteFile(traceLocation, trace, 0644); err != nil {
return fmt.Errorf("cannot write relocated trace: %w", err)
}
}
return runVM(*program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode)
},
},
{
Name: "cairo-run",
Usage: "runs a cairo zero compiled file",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "proofmode",
Usage: "runs the cairo vm in proof mode",
Required: false,
Destination: &proofmode,
},
&cli.Uint64Flag{
Name: "maxsteps",
Usage: "limits the execution steps to 'maxsteps'",
DefaultText: "2**64 - 1",
Value: math.MaxUint64,
Required: false,
Destination: &maxsteps,
},
&cli.Uint64Flag{
Name: "entrypoint",
Usage: "a PC offset that will be used as an entry point (by default it executes a main function)",
Value: 0,
Destination: &entrypointOffset,
},
&cli.BoolFlag{
Name: "collect_trace",
Usage: "collects the trace and builds the relocated trace after execution",
Required: false,
Destination: &collectTrace,
},
&cli.StringFlag{
Name: "tracefile",
Usage: "location to store the relocated trace",
Required: false,
Destination: &traceLocation,
},
&cli.BoolFlag{
Name: "build_memory",
Usage: "builds the relocated memory after execution",
Required: false,
Destination: &buildMemory,
},
&cli.StringFlag{
Name: "memoryfile",
Usage: "location to store the relocated memory",
Required: false,
Destination: &memoryLocation,
},
&cli.StringFlag{
Name: "layout",
Usage: "specifies the set of builtins to be used",
Required: false,
Destination: &layoutName,
},
&cli.StringFlag{
Name: "air_public_input",
Usage: "location to store the air_public_input",
Required: false,
Destination: &airPublicInputLocation,
},
&cli.StringFlag{
Name: "air_private_input",
Usage: "location to store the air_private_input",
Required: false,
Destination: &airPrivateInputLocation,
},
},
Action: func(ctx *cli.Context) error {
pathToFile := ctx.Args().Get(0)
if pathToFile == "" {
return fmt.Errorf("path to cairo file not set")
}

if proofmode || buildMemory {
memory, err := runner.BuildMemory()
if err != nil {
return fmt.Errorf("cannot build memory: %w", err)
}

if memoryLocation != "" {
if err := os.WriteFile(memoryLocation, memory, 0644); err != nil {
return fmt.Errorf("cannot write relocated memory: %w", err)
}
}
var hints map[uint64][]hinter.Hinter
var program *runner.Program
cairoProgram, err := starknet.StarknetProgramFromFile(pathToFile)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}

if proofmode {
if airPublicInputLocation != "" {
airPublicInput, err := runner.GetAirPublicInput()
if err != nil {
return err
}
airPublicInputJson, err := json.MarshalIndent(airPublicInput, "", " ")
if err != nil {
return err
}
err = os.WriteFile(airPublicInputLocation, airPublicInputJson, 0644)
if err != nil {
return fmt.Errorf("cannot write air_public_input: %w", err)
}
}

if airPrivateInputLocation != "" {
tracePath, err := filepath.Abs(traceLocation)
if err != nil {
return err
}
memoryPath, err := filepath.Abs(memoryLocation)
if err != nil {
return err
}
airPrivateInput, err := runner.GetAirPrivateInput(tracePath, memoryPath)
if err != nil {
return err
}
airPrivateInputJson, err := json.MarshalIndent(airPrivateInput, "", " ")
if err != nil {
return err
}
err = os.WriteFile(airPrivateInputLocation, airPrivateInputJson, 0644)
if err != nil {
return fmt.Errorf("cannot write air_private_input: %w", err)
}
}
hints, err = core.GetCairoHints(cairoProgram)
if err != nil {
return fmt.Errorf("cannot get hints: %w", err)
}

fmt.Println("Success!")
output := runner.Output()
if len(output) > 0 {
fmt.Println("Program output:")
for _, val := range output {
// cairo-run v0.11-0.13 pad the output lines with two spaces.
fmt.Printf(" %s\n", val)
}
program, err = runner.LoadCairoProgram(cairoProgram)
if err != nil {
return fmt.Errorf("cannot load program: %w", err)
}
runnerMode := runner.ExecutionMode
if proofmode {
runnerMode = runner.ProofModeCairo1
}
return nil
return runVM(*program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode)
},
},
},
Expand All @@ -270,3 +231,124 @@ func main() {
os.Exit(1)
}
}

func runVM(
program runner.Program,
proofmode bool,
maxsteps uint64,
entrypointOffset uint64,
collectTrace bool,
traceLocation string,
buildMemory bool,
memoryLocation string,
layoutName string,
airPublicInputLocation string,
airPrivateInputLocation string,
hints map[uint64][]hinter.Hinter,
runnerMode runner.RunnerMode,
) error {
fmt.Println("Running....")
runner, err := runner.NewRunner(&program, hints, runnerMode, collectTrace, maxsteps, layoutName)
if err != nil {
return fmt.Errorf("cannot create runner: %w", err)
}

// Run executes main(), RunEntryPoint is used to test contract_class-style entry points.
// In theory, calling RunEntryPoint with main's offset should behave identically,
// but these functions are implemented differently in both this and cairo-rs VMs
// and the difference is quite subtle.
if entrypointOffset == 0 {
if err := runner.Run(); err != nil {
return fmt.Errorf("runtime error: %w", err)
}
} else {
if err := runner.RunEntryPoint(entrypointOffset); err != nil {
return fmt.Errorf("runtime error (entrypoint=%d): %w", entrypointOffset, err)
}
}
if proofmode {
if err := runner.EndRun(); err != nil {
return fmt.Errorf("cannot end run: %w", err)
}
if err := runner.FinalizeSegments(); err != nil {
return fmt.Errorf("cannot finalize segments: %w", err)
}
}

if proofmode || collectTrace {
trace, err := runner.BuildTrace()
if err != nil {
return fmt.Errorf("cannot build trace: %w", err)
}

if traceLocation != "" {
if err := os.WriteFile(traceLocation, trace, 0644); err != nil {
return fmt.Errorf("cannot write relocated trace: %w", err)
}
}
}

if proofmode || buildMemory {
memory, err := runner.BuildMemory()
if err != nil {
return fmt.Errorf("cannot build memory: %w", err)
}

if memoryLocation != "" {
if err := os.WriteFile(memoryLocation, memory, 0644); err != nil {
return fmt.Errorf("cannot write relocated memory: %w", err)
}
}
}

if proofmode {
if airPublicInputLocation != "" {
airPublicInput, err := runner.GetAirPublicInput()
if err != nil {
return err
}
airPublicInputJson, err := json.MarshalIndent(airPublicInput, "", " ")
if err != nil {
return err
}
err = os.WriteFile(airPublicInputLocation, airPublicInputJson, 0644)
if err != nil {
return fmt.Errorf("cannot write air_public_input: %w", err)
}
}

if airPrivateInputLocation != "" {
tracePath, err := filepath.Abs(traceLocation)
if err != nil {
return err
}
memoryPath, err := filepath.Abs(memoryLocation)
if err != nil {
return err
}
airPrivateInput, err := runner.GetAirPrivateInput(tracePath, memoryPath)
if err != nil {
return err
}
airPrivateInputJson, err := json.MarshalIndent(airPrivateInput, "", " ")
if err != nil {
return err
}
err = os.WriteFile(airPrivateInputLocation, airPrivateInputJson, 0644)
if err != nil {
return fmt.Errorf("cannot write air_private_input: %w", err)
}
}
}

fmt.Println("Success!")
output := runner.Output()
if len(output) > 0 {
fmt.Println("Program output:")
for _, val := range output {
// cairo-run v0.11-0.13 pad the output lines with two spaces.
fmt.Printf(" %s\n", val)
}
}
return nil
}
1 change: 0 additions & 1 deletion integration_tests/cairozero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func runAndTestFile(t *testing.T, path string, name string, benchmarkMap map[str
t.Error(err)
return
}

elapsedPy, pyTraceFile, pyMemoryFile, err := runPythonVm(name, compiledOutput)
if errorExpected {
// we let the code go on so that we can check if the go vm also raises an error
Expand Down
Loading

0 comments on commit a9800e2

Please sign in to comment.