Skip to content

Commit

Permalink
feat: add zero parser and test (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
krafugo committed Sep 6, 2023
1 parent 5c7b36f commit f533a36
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
require (
github.com/consensys/gnark-crypto v0.11.1
github.com/go-playground/validator/v10 v10.4.1
github.com/go-test/deep v1.1.0
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
Expand Down
67 changes: 67 additions & 0 deletions pkg/parsers/zero/zero.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package zero

import (
"encoding/json"
"os"
)

type ZeroProgram struct {
Attributes []string `json:"attributes"`
Builtins map[string]int64 `json:"builtins"`
Code string `json:"code"`
DebugInfo DebugInfo `json:"debug_info"`
Prime string `json:"prime"`
Version string `json:"version"`
Hints map[string][]Hint `json:"hints"`
}

type DebugInfo struct {
InstructionOffsets []int64 `json:"instruction_offsets"`
SourceCode string `json:"source_code"`
SourcePath string `json:"source_path"`
}

type Hint struct {
AccessibleScopes []string `json:"accessible_scopes"`
Code string `json:"code"`
FlowTrackingData FlowTrackingData `json:"flow_tracking_data"`
}

type FlowTrackingData struct {
ApTracking ApTracking `json:"ap_tracking"`
ReferenceIds map[string]interface{} `json:"reference_ids"`
}

type ApTracking struct {
Group int `json:"group"`
Offset int `json:"offset"`
}

func (z ZeroProgram) MarshalToFile(filepath string) error {
// Marshal Output struct into JSON bytes
data, err := json.MarshalIndent(z, "", " ")
if err != nil {
return err
}

// Write JSON bytes to file
err = os.WriteFile(filepath, data, 0644)
if err != nil {
return err
}

return nil
}

func ZeroProgramFromFile(filepath string) (zero *ZeroProgram, err error) {
content, err := os.ReadFile(filepath)
if err != nil {
return
}
return ZeroProgramFromJSON(content)
}

func ZeroProgramFromJSON(content json.RawMessage) (*ZeroProgram, error) {
var zero ZeroProgram
return &zero, json.Unmarshal(content, &zero)
}
105 changes: 105 additions & 0 deletions pkg/parsers/zero/zero_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package zero

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
)

func TestZeroParse(t *testing.T) {
tests := []struct {
name string
jsonData string
expected ZeroProgram
}{
{
name: "Attributes field",
jsonData: `
{
"attributes": ["attr1", "attr2"]
}`,
expected: ZeroProgram{
Attributes: []string{"attr1", "attr2"},
},
},
{
name: "Builtins field",
jsonData: `
{
"builtins": {"builtin1": 1, "builtin2": 2}
}`,
expected: ZeroProgram{
Builtins: map[string]int64{"builtin1": 1, "builtin2": 2},
},
},
{
name: "Code field",
jsonData: `
{
"code": "some code sample"
}`,
expected: ZeroProgram{
Code: "some code sample",
},
},
{
name: "Version field",
jsonData: `
{
"version": "0.12.2"
}`,
expected: ZeroProgram{
Version: "0.12.2",
},
},
{
name: "Prime field",
jsonData: `
{
"prime": "0x800000000000011000000000000000000000000000000000000000000000001"
}`,
expected: ZeroProgram{
Prime: "0x800000000000011000000000000000000000000000000000000000000000001",
},
},
{
name: "Hints field",
jsonData: `
{
"hints": {
"0": [
{
"accessible_scopes": [
"starkware.cairo.common.math",
"starkware.cairo.common.math.assert_not_equal"
],
"code": "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'"
}
]
}
}`,
expected: ZeroProgram{
Hints: map[string][]Hint{
"0": {{
AccessibleScopes: []string{"starkware.cairo.common.math", "starkware.cairo.common.math.assert_not_equal"},
Code: "from starkware.cairo.lang.vm.relocatable import RelocatableValue\nboth_ints = isinstance(ids.a, int) and isinstance(ids.b, int)\nboth_relocatable = (\n isinstance(ids.a, RelocatableValue) and isinstance(ids.b, RelocatableValue) and\n ids.a.segment_index == ids.b.segment_index)\nassert both_ints or both_relocatable, \\\n f'assert_not_equal failed: non-comparable values: {ids.a}, {ids.b}.'\nassert (ids.a - ids.b) % PRIME != 0, f'assert_not_equal failed: {ids.a} = {ids.b}.'",
}},
},
},
},
// TODO: Add debug-info test case
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var z ZeroProgram
err := json.Unmarshal([]byte(tt.jsonData), &z)
if err != nil {
t.Errorf("Failed to unmarshal JSON: %s", err)
}

assert.Equal(t, tt.expected, z, "Field does not match")
})
}
}

0 comments on commit f533a36

Please sign in to comment.