Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add available gas and user args #677

Merged
merged 21 commits into from
Dec 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
b6f59e0
Add parsing logic for input user args
MaksymMalicki Dec 13, 2024
3cce170
Add flags for available gas, input user args, writing args to memory
MaksymMalicki Dec 13, 2024
9e2d84b
Fix unit tests for user arguments parsing
MaksymMalicki Dec 13, 2024
316a872
Lint the PR
MaksymMalicki Dec 13, 2024
7753686
Add user args to hint context
MaksymMalicki Dec 16, 2024
9c4fb34
Refactor the code
MaksymMalicki Dec 16, 2024
5869a28
Fix unconditional append of ExternalWriteArgsToMemory, bug fixes in i…
MaksymMalicki Dec 16, 2024
2948824
Add fixes of the call size calculation and include ExternalWriteArgsT…
MaksymMalicki Dec 17, 2024
1adfe24
Add layouts for integration tests
MaksymMalicki Dec 17, 2024
73480e3
Add error handling
MaksymMalicki Dec 17, 2024
747e93d
Fixes in entry code generation
MaksymMalicki Dec 17, 2024
3d3a537
Address changes mentioned in a discussion
MaksymMalicki Dec 20, 2024
5ff5874
Add comment regarding writing to memory in a hint for the future refe…
MaksymMalicki Dec 20, 2024
77d8516
Changes in calculations of the initial PC offset, CALL opcode offset …
MaksymMalicki Dec 25, 2024
e8b9615
Turn back VM config to private field
MaksymMalicki Dec 25, 2024
dc209dc
Add error handling on assign of `userArgs` to the initial scope
MaksymMalicki Dec 25, 2024
d8b6e64
Lint project
MaksymMalicki Dec 25, 2024
4941781
Bump go version from 1.20 -> 1.21 (#678)
MaksymMalicki Dec 25, 2024
03f3f22
Simplify the Makefile
MaksymMalicki Dec 25, 2024
236f757
Merge branch 'add_available_gas_and_user_args' of https://github.com/…
MaksymMalicki Dec 25, 2024
f6e723e
Correction in the makefile
MaksymMalicki Dec 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
go-version: '1.21'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.53.3
version: v1.55.2

# Optional: working directory, useful for monorepos
# working-directory: somedir
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: "1.20"
go-version: "1.21"

- name: Build
run: make build
Expand Down
38 changes: 18 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,31 +41,29 @@ integration:
@echo "Running integration tests..."
@$(MAKE) build
@if [ $$? -eq 0 ]; then \
if [ ! -d ./rust_vm_bin ]; then \
mkdir -p ./rust_vm_bin; \
if [ ! -d rust_vm_bin ]; then \
mkdir -p rust_vm_bin; \
fi; \
if [ ! -d ./rust_vm_bin/cairo ]; then \
mkdir -p ./rust_vm_bin/cairo; \
if [ ! -d rust_vm_bin/cairo ]; then \
mkdir -p rust_vm_bin/cairo-lang; \
fi; \
if [ ! -f ./rust_vm_bin/cairo/cairo-compile ] || [ ! -f ./rust_vm_bin/cairo/sierra-compile-json ] || [ ! -d ./rust_vm_bin/corelib ]; then \
cd ./rust_vm_bin/cairo; \
if [ ! -f ./rust_vm_bin/cairo-lang/cairo-compile ] || [ ! -f ./rust_vm_bin/cairo-lang/sierra-compile-json ] || [ ! -d rust_vm_bin/corelib ]; then \
cd rust_vm_bin; \
git clone --single-branch --branch feat/main-casm-json --depth=1 https://github.com/zmalatrax/cairo.git; \
mv cairo/corelib ../../rust_vm_bin/; \
cd cairo/crates/bin && \
cargo build --release --bin cairo-compile --bin sierra-compile-json && \
cd ../../../; \
mv cairo/target/release/cairo-compile cairo/target/release/sierra-compile-json ../cairo/ && \
rm -rf ./cairo; \
mv cairo/corelib .; \
cd cairo/crates/bin && cargo build --release --bin cairo-compile --bin sierra-compile-json && cd ../../../; \
mv cairo/target/release/cairo-compile cairo/target/release/sierra-compile-json cairo-lang; \
rm -rf cairo; \
cd ../; \
fi; \
if [ ! -f ./rust_vm_bin/cairo/cairo1-run ] || [ ! -f ./rust_vm_bin/cairo-vm-cli ]; then \
cd ./rust_vm_bin; \
git clone https://github.com/lambdaclass/cairo-vm.git && \
cd cairo-vm/; \
cargo build --release --bin cairo-vm-cli --bin cairo1-run; \
mv cairo-vm/target/release/cairo1-run ./cairo/ && \
mv cairo-vm/target/release/cairo-vm-cli ../rust_vm_bin/ && \
if [ ! -f ./rust_vm_bin/cairo-lang/cairo1-run ] || [ ! -f ./rust_vm_bin/cairo-vm-cli ]; then \
cd rust_vm_bin; \
git clone https://github.com/lambdaclass/cairo-vm.git; \
cd cairo-vm && cargo build --release --bin cairo-vm-cli --bin cairo1-run && cd ../; \
mv cairo-vm/target/release/cairo1-run cairo-lang;\
mv cairo-vm/target/release/cairo-vm-cli . ; \
rm -rf cairo-vm; \
cd ../../; \
cd ../; \
fi; \
go test ./integration_tests/... -v; \
else \
Expand Down
34 changes: 31 additions & 3 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/NethermindEth/cairo-vm-go/pkg/parsers/starknet"
zero "github.com/NethermindEth/cairo-vm-go/pkg/parsers/zero"
"github.com/NethermindEth/cairo-vm-go/pkg/runner"
"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
"github.com/urfave/cli/v2"
)

Expand All @@ -26,6 +27,8 @@ func main() {
var layoutName string
var airPublicInputLocation string
var airPrivateInputLocation string
var args string
var availableGas uint64
app := &cli.App{
Name: "cairo-vm",
Usage: "A cairo virtual machine",
Expand Down Expand Up @@ -122,7 +125,7 @@ func main() {
if proofmode {
runnerMode = runner.ProofModeCairo0
}
return runVM(*program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode)
return runVM(*program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode, nil)
},
},
{
Expand Down Expand Up @@ -191,6 +194,18 @@ func main() {
Required: false,
Destination: &airPrivateInputLocation,
},
&cli.StringFlag{
Name: "args",
Usage: "input arguments for the `main` function in the cairo progran",
Required: false,
Destination: &args,
},
&cli.Uint64Flag{
Name: "available_gas",
Usage: "available gas for the VM execution",
Required: false,
Destination: &availableGas,
},
},
Action: func(ctx *cli.Context) error {
pathToFile := ctx.Args().Get(0)
Expand All @@ -210,7 +225,19 @@ func main() {
if proofmode {
runnerMode = runner.ProofModeCairo1
}
return runVM(program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode)
userArgs, err := starknet.ParseCairoProgramArgs(args)
if err != nil {
return fmt.Errorf("cannot parse args: %w", err)
}
if availableGas > 0 {
// The first argument is the available gas
availableGasArg := starknet.CairoFuncArgs{
Single: new(fp.Element).SetUint64(availableGas),
Array: nil,
}
userArgs = append([]starknet.CairoFuncArgs{availableGasArg}, userArgs...)
}
return runVM(program, proofmode, maxsteps, entrypointOffset, collectTrace, traceLocation, buildMemory, memoryLocation, layoutName, airPublicInputLocation, airPrivateInputLocation, hints, runnerMode, userArgs)
},
},
},
Expand All @@ -236,9 +263,10 @@ func runVM(
airPrivateInputLocation string,
hints map[uint64][]hinter.Hinter,
runnerMode runner.RunnerMode,
userArgs []starknet.CairoFuncArgs,
) error {
fmt.Println("Running....")
runner, err := runner.NewRunner(&program, hints, runnerMode, collectTrace, maxsteps, layoutName)
runner, err := runner.NewRunner(&program, hints, runnerMode, collectTrace, maxsteps, layoutName, userArgs)
if err != nil {
return fmt.Errorf("cannot create runner: %w", err)
}
Expand Down
8 changes: 5 additions & 3 deletions integration_tests/cairo_vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,16 +459,18 @@ func runVm(path, layout string, zero bool) (time.Duration, string, string, strin
}
args := []string{
cliCommand,
"--proofmode",
// "--proofmode",
"--tracefile",
traceOutput,
"--memoryfile",
memoryOutput,
"--layout",
layout,
path,
}

if !zero {
args = append(args, "--available_gas", "9999999")
}
args = append(args, path)
cmd := exec.Command(
"../bin/cairo-vm",
args...,
Expand Down
35 changes: 35 additions & 0 deletions pkg/hintrunner/core/hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -1929,3 +1929,38 @@ func (hint *FieldSqrt) Execute(vm *VM.VirtualMachine, _ *hinter.HintRunnerContex

return vm.Memory.WriteToAddress(&sqrtAddr, &sqrtVal)
}

type ExternalWriteArgsToMemory struct{}

func (hint *ExternalWriteArgsToMemory) String() string {
return "ExternalWriteToMemory"
}

func (hint *ExternalWriteArgsToMemory) Execute(vm *VM.VirtualMachine, ctx *hinter.HintRunnerContext) error {
userArgsVar, err := ctx.ScopeManager.GetVariableValue("userArgs")
if err != nil {
return fmt.Errorf("get user args: %v", err)
}
userArgs, ok := userArgsVar.([]starknet.CairoFuncArgs)
if !ok {
return fmt.Errorf("expected user args to be a list of CairoFuncArgs")
}
for _, arg := range userArgs {
if arg.Single != nil {
mv := mem.MemoryValueFromFieldElement(arg.Single)
err := vm.Memory.Write(1, vm.Context.Ap, &mv)
if err != nil {
return fmt.Errorf("write single arg: %v", err)
cicr99 marked this conversation as resolved.
Show resolved Hide resolved
}
} else if arg.Array != nil {
arrayBase := vm.Memory.AllocateEmptySegment()
mv := mem.MemoryValueFromMemoryAddress(&arrayBase)
err := vm.Memory.Write(1, vm.Context.Ap, &mv)
if err != nil {
return fmt.Errorf("write array base: %v", err)
}
// TODO: Implement array writing
}
}
return nil
}
12 changes: 10 additions & 2 deletions pkg/hintrunner/hintrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

h "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/hinter"
"github.com/NethermindEth/cairo-vm-go/pkg/parsers/starknet"
VM "github.com/NethermindEth/cairo-vm-go/pkg/vm"
)

Expand All @@ -14,11 +15,18 @@ type HintRunner struct {
hints map[uint64][]h.Hinter
}

func NewHintRunner(hints map[uint64][]h.Hinter) HintRunner {
func NewHintRunner(hints map[uint64][]h.Hinter, userArgs []starknet.CairoFuncArgs) HintRunner {
context := *h.InitializeDefaultContext()
if userArgs != nil {
err := context.ScopeManager.AssignVariable("userArgs", userArgs)
if err != nil {
panic(fmt.Errorf("assign userArgs: %v", err))
}
}
return HintRunner{
// Context for certain hints that require it. Each manager is
// initialized only when required by the hint
context: *h.InitializeDefaultContext(),
context: context,
hints: hints,
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/hintrunner/hintrunner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestExistingHint(t *testing.T) {

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

vm.Context.Pc = memory.MemoryAddress{
SegmentIndex: 0,
Expand All @@ -44,7 +44,7 @@ func TestNoHint(t *testing.T) {

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

vm.Context.Pc = memory.MemoryAddress{
SegmentIndex: 0,
Expand Down
56 changes: 56 additions & 0 deletions pkg/parsers/starknet/args.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package starknet

import (
"fmt"
"regexp"
"strings"

"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
)

type CairoFuncArgs struct {
Single *fp.Element
Array []fp.Element
}

func ParseCairoProgramArgs(input string) ([]CairoFuncArgs, error) {
re := regexp.MustCompile(`\[[^\]]*\]|\S+`)
tokens := re.FindAllString(input, -1)
var result []CairoFuncArgs

parseValueToFelt := func(token string) (*fp.Element, error) {
felt, err := new(fp.Element).SetString(token)
if err != nil {
return nil, fmt.Errorf("invalid felt value: %v", err)
}
return felt, nil
}

for _, token := range tokens {
if single, err := parseValueToFelt(token); err == nil {
result = append(result, CairoFuncArgs{
Single: single,
Array: nil,
})
} else if strings.HasPrefix(token, "[") && strings.HasSuffix(token, "]") {
arrayStr := strings.Trim(token, "[]")
arrayElements := strings.Fields(arrayStr)
array := make([]fp.Element, len(arrayElements))
for i, element := range arrayElements {
single, err := parseValueToFelt(element)
if err != nil {
return nil, fmt.Errorf("invalid felt value in array: %v", err)
}
array[i] = *single
}
result = append(result, CairoFuncArgs{
Single: nil,
Array: array,
})
} else {
return nil, fmt.Errorf("invalid token: %s", token)
}
}

return result, nil
}
Loading
Loading