From e474793273f9abba48c8a66210fb1f6593ac9b6c Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Mon, 31 Jul 2023 16:40:32 -0400 Subject: [PATCH 1/5] feat: Add entry point parsing to casm program --- pkg/vm/program.go | 94 +++++++++++++++++++++++++++++++++++--- pkg/vm/program_test.go | 100 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 186 insertions(+), 8 deletions(-) diff --git a/pkg/vm/program.go b/pkg/vm/program.go index 09025055..6cfc3f2a 100644 --- a/pkg/vm/program.go +++ b/pkg/vm/program.go @@ -2,20 +2,102 @@ package vm import ( "encoding/json" + "fmt" "os" + "strconv" f "github.com/NethermindEth/juno/core/felt" ) +type Builtin uint8 + +const ( + Output Builtin = iota + 1 + RangeCheck + Pedersen + ECDSA + Keccak + Bitwise + ECOP + Poseidon + SegmentArena +) + +func (b Builtin) MarshalJSON() ([]byte, error) { + switch b { + case Output: + return []byte("output"), nil + case RangeCheck: + return []byte("range_check"), nil + case Pedersen: + return []byte("pedersen"), nil + case ECDSA: + return []byte("ecdsa"), nil + case Keccak: + return []byte("keccak"), nil + case Bitwise: + return []byte("bitwise"), nil + case ECOP: + return []byte("ec_op"), nil + case Poseidon: + return []byte("poseidon"), nil + case SegmentArena: + return []byte("segment_arena"), nil + + } + return nil, fmt.Errorf("Error marshaling builtin with unknow identifer: %d", uint8(b)) +} + +func (b *Builtin) UnmarshalJSON(data []byte) error { + builtinName, err := strconv.Unquote(string(data)) + if err != nil { + return fmt.Errorf("Error unmarsahling builtin: %w", err) + } + + switch builtinName { + case "output": + *b = Output + case "range_check": + *b = RangeCheck + case "pedersen": + *b = Pedersen + case "ecdsa": + *b = ECDSA + case "keccak": + *b = Keccak + case "bitwise": + *b = Bitwise + case "ec_op": + *b = ECOP + case "poseidon": + *b = Poseidon + case "segment_arena": + *b = SegmentArena + default: + return fmt.Errorf("Error unmarsahling unknwon builtin name: %s", builtinName) + } + return nil +} + +type EntryPointInfo struct { + Selector f.Felt `json:"selector"` + Offset f.Felt `json:"offset"` + Builtins []Builtin `json:"builtins"` +} + +type EntryPointByType struct { + External []EntryPointInfo `json:"EXTERNAL"` + L1Handler []EntryPointInfo `json:"L1_HANDLER"` + Constructor []EntryPointInfo `json:"CONSTRUCTOR"` +} + type Program struct { // Prime is fixed to be 0x800000000000011000000000000000000000000000000000000000000000001 and wont fit in a f.Felt - Bytecode []f.Felt `json:"bytecode"` - CompilerVersion string `json:"compiler_version"` - // todo(rodro): Add remaining Json fields + Bytecode []f.Felt `json:"bytecode"` + CompilerVersion string `json:"compiler_version"` + EntryPoints EntryPointByType `json:"entry_points_by_type"` + // todo(rodro): Add remaining Json field // Hints - // EntryPointsByType - // Contructors - // L1 Headers } func ProgramFromFile(pathToFile string) (*Program, error) { diff --git a/pkg/vm/program_test.go b/pkg/vm/program_test.go index 2fc48320..eaf4d2ee 100644 --- a/pkg/vm/program_test.go +++ b/pkg/vm/program_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestValidPrime(t *testing.T) { +func TestCompilerVersionParsing(t *testing.T) { testData := []byte(` { "compiler_version": "2.1.0", @@ -22,11 +22,107 @@ func TestValidPrime(t *testing.T) { program, err := ProgramFromJSON(testData) require.NoError(t, err) assert.Equal(t, "2.1.0", program.CompilerVersion) +} + +func TestByteCodeParsing(t *testing.T) { + testData := []byte(` + { + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000" + ] + } + `) + program, err := ProgramFromJSON(testData) + require.NoError(t, err) assert.Len(t, program.Bytecode, 4) assert.Equal(t, "0x482680017ffa8000", program.Bytecode[2].String()) } -func TestInvalidPrime(t *testing.T) { +func TestEmptyEntryPointTypeParsing(t *testing.T) { + testData := []byte(` + { + "entry_points_by_selector": { + "EXTERNAL": [], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } + } + `) + program, err := ProgramFromJSON(testData) + require.NoError(t, err) + + entryPoints := program.EntryPoints + assert.Len(t, entryPoints.External, 0) + assert.Len(t, entryPoints.L1Handler, 0) + assert.Len(t, entryPoints.Constructor, 0) + +} + +func TestEntryPointInfoParsing(t *testing.T) { + testData := []byte(` + { + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xabcdef0123456789", + "offset": 14, + "builtins": [ + "output", + "range_check", + "pedersen", + "ecdsa", + "keccak", + "bitwise", + "ec_op", + "poseidon", + "segment_arena" + ] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } + } + `) + program, err := ProgramFromJSON(testData) + require.NoError(t, err) + + entryPoints := program.EntryPoints + assert.Len(t, entryPoints.External, 1) + + entryPointInfo := entryPoints.External[0] + assert.Equal(t, entryPointInfo.Selector.String(), "0xabcdef0123456789") + assert.Equal(t, entryPointInfo.Offset.String(), "0xe") + + assert.Len(t, entryPointInfo.Builtins, 9) + for i := 0; i < 9; i++ { + assert.Equal(t, Builtin(i + 1), entryPointInfo.Builtins[i]) + } +} + +func TestInvalidBuiltin(t *testing.T) { + testData := []byte(` + { + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0xabcdef0123456789", + "offset": 14, + "builtins": [ + "pedrsen", + ] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } + } + `) + _, err := ProgramFromJSON(testData) + assert.NotNil(t, err) } From d0bdeeb3f11a9f5f7a4e59f623f9f6345a2784fe Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Tue, 1 Aug 2023 01:14:01 -0400 Subject: [PATCH 2/5] Formatting --- pkg/vm/program_test.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/pkg/vm/program_test.go b/pkg/vm/program_test.go index eaf4d2ee..77d070e0 100644 --- a/pkg/vm/program_test.go +++ b/pkg/vm/program_test.go @@ -10,13 +10,7 @@ import ( func TestCompilerVersionParsing(t *testing.T) { testData := []byte(` { - "compiler_version": "2.1.0", - "bytecode": [ - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000" - ] + "compiler_version": "2.1.0" } `) program, err := ProgramFromJSON(testData) @@ -100,7 +94,7 @@ func TestEntryPointInfoParsing(t *testing.T) { assert.Len(t, entryPointInfo.Builtins, 9) for i := 0; i < 9; i++ { - assert.Equal(t, Builtin(i + 1), entryPointInfo.Builtins[i]) + assert.Equal(t, Builtin(i+1), entryPointInfo.Builtins[i]) } } @@ -123,6 +117,6 @@ func TestInvalidBuiltin(t *testing.T) { } `) _, err := ProgramFromJSON(testData) - assert.NotNil(t, err) + assert.NotNil(t, err) } From b882198ca286f224b905066108434bfd3f97ddbe Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Tue, 1 Aug 2023 01:19:59 -0400 Subject: [PATCH 3/5] Error to lower case --- pkg/vm/program.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/vm/program.go b/pkg/vm/program.go index 6cfc3f2a..a601fddc 100644 --- a/pkg/vm/program.go +++ b/pkg/vm/program.go @@ -45,14 +45,14 @@ func (b Builtin) MarshalJSON() ([]byte, error) { return []byte("segment_arena"), nil } - return nil, fmt.Errorf("Error marshaling builtin with unknow identifer: %d", uint8(b)) + return nil, fmt.Errorf("error marshaling builtin with unknow identifer: %d", uint8(b)) } func (b *Builtin) UnmarshalJSON(data []byte) error { builtinName, err := strconv.Unquote(string(data)) - if err != nil { - return fmt.Errorf("Error unmarsahling builtin: %w", err) - } + if err != nil { + return fmt.Errorf("error unmarsahling builtin: %w", err) + } switch builtinName { case "output": @@ -73,10 +73,10 @@ func (b *Builtin) UnmarshalJSON(data []byte) error { *b = Poseidon case "segment_arena": *b = SegmentArena - default: - return fmt.Errorf("Error unmarsahling unknwon builtin name: %s", builtinName) + default: + return fmt.Errorf("error unmarsahling unknwon builtin name: %s", builtinName) } - return nil + return nil } type EntryPointInfo struct { From 7d9105d6a202edbd7a535cf397f5fea32d763afc Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Tue, 1 Aug 2023 01:24:06 -0400 Subject: [PATCH 4/5] Use assert.Empty(...) --- pkg/vm/program_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/vm/program_test.go b/pkg/vm/program_test.go index 77d070e0..d4658aec 100644 --- a/pkg/vm/program_test.go +++ b/pkg/vm/program_test.go @@ -50,9 +50,9 @@ func TestEmptyEntryPointTypeParsing(t *testing.T) { require.NoError(t, err) entryPoints := program.EntryPoints - assert.Len(t, entryPoints.External, 0) - assert.Len(t, entryPoints.L1Handler, 0) - assert.Len(t, entryPoints.Constructor, 0) + assert.Empty(t, entryPoints.External) + assert.Empty(t, entryPoints.L1Handler) + assert.Empty(t, entryPoints.Constructor) } From 62489b5a98953168dcfb61e3b96e0aca8fadd6bf Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Tue, 1 Aug 2023 14:20:02 -0400 Subject: [PATCH 5/5] Change assertion --- pkg/vm/program_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/vm/program_test.go b/pkg/vm/program_test.go index d4658aec..e1687e2d 100644 --- a/pkg/vm/program_test.go +++ b/pkg/vm/program_test.go @@ -117,6 +117,6 @@ func TestInvalidBuiltin(t *testing.T) { } `) _, err := ProgramFromJSON(testData) - assert.NotNil(t, err) + assert.Error(t, err) }