From 949844154b295441417045f24a9d92947d54ab33 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 9 Oct 2024 01:42:21 +0400 Subject: [PATCH 1/8] Add starknet_getCompiledCasm (working for cairo1 for now) --- rpc/executables.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++ rpc/handlers.go | 6 ++++ sync/sync.go | 4 +-- 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 rpc/executables.go diff --git a/rpc/executables.go b/rpc/executables.go new file mode 100644 index 0000000000..8f88212f31 --- /dev/null +++ b/rpc/executables.go @@ -0,0 +1,81 @@ +package rpc + +import ( + "encoding/json" + "fmt" + "github.com/NethermindEth/juno/core" + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/jsonrpc" + "github.com/NethermindEth/juno/utils" +) + +type CasmEntryPoint struct { + Offset *felt.Felt `json:"offset"` + Selector *felt.Felt `json:"selector"` + Builtins []string `json:"builtins"` +} + +type EntryPointsByType struct { + Constructor []CasmEntryPoint `json:"CONSTRUCTOR"` + External []CasmEntryPoint `json:"EXTERNAL"` + L1Handler []CasmEntryPoint `json:"L1_HANDLER"` +} + +type CasmCompiledContractClass struct { + EntryPointsByType EntryPointsByType `json:"entry_points_by_type"` + Prime *felt.Felt `json:"prime"` + CompilerVersion string `json:"compiler_version"` + Bytecode []*felt.Felt `json:"bytecode"` + Hints json.RawMessage `json:"hints"` + BytecodeSegmentLengths []int `json:"bytecode_segment_lengths,omitempty"` +} + +func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass, *jsonrpc.Error) { + rd, stateCloser, err := h.bcReader.HeadState() + if err != nil { + return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) + } + defer h.callAndLogErr(stateCloser, "failed to close state reader") + + declaredClass, err := rd.Class(classHash) + if err != nil { + return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) + } + + switch class := declaredClass.Class.(type) { + case *core.Cairo0Class: + program, err := utils.Gzip64Decode(class.Program) + if err != nil { + return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) + } + fmt.Println(string(program)) + case *core.Cairo1Class: + return adaptCompiledClass(class.Compiled) + } + + return nil, jsonrpc.Err(jsonrpc.InternalError, "unsupported class type") +} + +func adaptCompiledClass(class *core.CompiledClass) (*CasmCompiledContractClass, *jsonrpc.Error) { + adaptEntryPoint := func(ep core.CompiledEntryPoint) CasmEntryPoint { + return CasmEntryPoint{ + Offset: new(felt.Felt).SetUint64(ep.Offset), + Selector: ep.Selector, + Builtins: ep.Builtins, + } + } + + result := &CasmCompiledContractClass{ + EntryPointsByType: EntryPointsByType{ + Constructor: utils.Map(class.Constructor, adaptEntryPoint), + External: utils.Map(class.External, adaptEntryPoint), + L1Handler: utils.Map(class.L1Handler, adaptEntryPoint), + }, + Prime: new(felt.Felt).SetBigInt(class.Prime), + CompilerVersion: class.CompilerVersion, + Bytecode: class.Bytecode, + Hints: class.Hints, + BytecodeSegmentLengths: nil, // todo fill this + } + return result, nil +} diff --git a/rpc/handlers.go b/rpc/handlers.go index cfaf1f37a1..f9bbba510a 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -326,6 +326,12 @@ func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen Params: []jsonrpc.Parameter{{Name: "block_id"}}, Handler: h.BlockWithReceipts, }, + // temporary, todo change it to 0.8 methods + { + Name: "starknet_getCompiledCasm", + Params: []jsonrpc.Parameter{{Name: "class_hash"}}, + Handler: h.CompiledCasm, + }, }, "/v0_7" } diff --git a/sync/sync.go b/sync/sync.go index a2e4ac0bf0..91dec9e4a0 100644 --- a/sync/sync.go +++ b/sync/sync.go @@ -229,8 +229,8 @@ func (s *Synchronizer) verifierTask(ctx context.Context, block *core.Block, stat } s.newHeads.Send(block.Header) - s.log.Infow("Stored Block", "number", block.Number, "hash", - block.Hash.ShortString(), "root", block.GlobalStateRoot.ShortString()) + //s.log.Infow("Stored Block", "number", block.Number, "hash", + // block.Hash.ShortString(), "root", block.GlobalStateRoot.ShortString()) } } } From 4f48ab9a6b67b7ce8acebd3128977adec65c3f0a Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 23 Oct 2024 00:18:46 +0400 Subject: [PATCH 2/8] Support cairo0 in new endpoint --- rpc/executables.go | 62 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/rpc/executables.go b/rpc/executables.go index 8f88212f31..9b16ea5d6e 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -2,7 +2,6 @@ package rpc import ( "encoding/json" - "fmt" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/jsonrpc" @@ -31,24 +30,24 @@ type CasmCompiledContractClass struct { } func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass, *jsonrpc.Error) { - rd, stateCloser, err := h.bcReader.HeadState() + state, stateCloser, err := h.bcReader.HeadState() if err != nil { return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } defer h.callAndLogErr(stateCloser, "failed to close state reader") - declaredClass, err := rd.Class(classHash) + declaredClass, err := state.Class(classHash) if err != nil { return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } switch class := declaredClass.Class.(type) { case *core.Cairo0Class: - program, err := utils.Gzip64Decode(class.Program) + resp, err := adaptCairo0Class(class) if err != nil { return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } - fmt.Println(string(program)) + return resp, nil case *core.Cairo1Class: return adaptCompiledClass(class.Compiled) } @@ -56,6 +55,44 @@ func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass return nil, jsonrpc.Err(jsonrpc.InternalError, "unsupported class type") } +func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, error) { + program, err := utils.Gzip64Decode(class.Program) + if err != nil { + return nil, err + } + + var cairo0 struct { + Prime *felt.Felt + Data []*felt.Felt + } + err = json.Unmarshal(program, &cairo0) + if err != nil { + return nil, err + } + + adaptEntryPoint := func(ep core.EntryPoint) CasmEntryPoint { + return CasmEntryPoint{ + Offset: ep.Offset, + Selector: ep.Selector, + Builtins: nil, + } + } + + result := &CasmCompiledContractClass{ + EntryPointsByType: EntryPointsByType{ + Constructor: utils.Map(class.Constructors, adaptEntryPoint), + External: utils.Map(class.Externals, adaptEntryPoint), + L1Handler: utils.Map(class.L1Handlers, adaptEntryPoint), + }, + Prime: cairo0.Prime, + Bytecode: cairo0.Data, + CompilerVersion: "", + Hints: nil, + BytecodeSegmentLengths: nil, + } + return result, nil +} + func adaptCompiledClass(class *core.CompiledClass) (*CasmCompiledContractClass, *jsonrpc.Error) { adaptEntryPoint := func(ep core.CompiledEntryPoint) CasmEntryPoint { return CasmEntryPoint{ @@ -75,7 +112,20 @@ func adaptCompiledClass(class *core.CompiledClass) (*CasmCompiledContractClass, CompilerVersion: class.CompilerVersion, Bytecode: class.Bytecode, Hints: class.Hints, - BytecodeSegmentLengths: nil, // todo fill this + BytecodeSegmentLengths: collectSegmentLengths(class.BytecodeSegmentLengths), } return result, nil } + +func collectSegmentLengths(segmentLengths core.SegmentLengths) []int { + if len(segmentLengths.Children) == 0 { + return []int{int(segmentLengths.Length)} + } + + var result []int + for _, child := range segmentLengths.Children { + result = append(result, collectSegmentLengths(child)...) + } + + return result +} From 990fd64ef2f2e5fee7803b5db5598329f9679273 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 23 Oct 2024 00:28:17 +0400 Subject: [PATCH 3/8] Fix linter issues --- rpc/executables.go | 7 ++++--- rpc/handlers.go | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/rpc/executables.go b/rpc/executables.go index 9b16ea5d6e..3771eed9a8 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -2,6 +2,7 @@ package rpc import ( "encoding/json" + "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/jsonrpc" @@ -49,7 +50,7 @@ func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass } return resp, nil case *core.Cairo1Class: - return adaptCompiledClass(class.Compiled) + return adaptCompiledClass(class.Compiled), nil } return nil, jsonrpc.Err(jsonrpc.InternalError, "unsupported class type") @@ -93,7 +94,7 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro return result, nil } -func adaptCompiledClass(class *core.CompiledClass) (*CasmCompiledContractClass, *jsonrpc.Error) { +func adaptCompiledClass(class *core.CompiledClass) *CasmCompiledContractClass { adaptEntryPoint := func(ep core.CompiledEntryPoint) CasmEntryPoint { return CasmEntryPoint{ Offset: new(felt.Felt).SetUint64(ep.Offset), @@ -114,7 +115,7 @@ func adaptCompiledClass(class *core.CompiledClass) (*CasmCompiledContractClass, Hints: class.Hints, BytecodeSegmentLengths: collectSegmentLengths(class.BytecodeSegmentLengths), } - return result, nil + return result } func collectSegmentLengths(segmentLengths core.SegmentLengths) []int { diff --git a/rpc/handlers.go b/rpc/handlers.go index 88f25e2161..f0da743528 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -170,7 +170,7 @@ func (h *Handler) SpecVersionV0_7() (string, *jsonrpc.Error) { return "0.7.1", nil } -func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen, dupl +func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen return []jsonrpc.Method{ { Name: "starknet_chainId", @@ -328,7 +328,7 @@ func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen, dupl }, "/v0_8" } -func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen, dupl +func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen return []jsonrpc.Method{ { Name: "starknet_chainId", From 4788f92e08321e0a6c5a2eaefb57a5df7e4e0cc3 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 23 Oct 2024 15:28:28 +0400 Subject: [PATCH 4/8] Add tests and fill data for Cairo0 --- adapters/core2sn/class.go | 3 +- rpc/executables.go | 26 ++++++----- rpc/executables_test.go | 92 +++++++++++++++++++++++++++++++++++++++ rpc/handlers.go | 11 +++-- utils/bigint.go | 9 ++++ 5 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 rpc/executables_test.go create mode 100644 utils/bigint.go diff --git a/adapters/core2sn/class.go b/adapters/core2sn/class.go index 34789353a3..d07740b81f 100644 --- a/adapters/core2sn/class.go +++ b/adapters/core2sn/class.go @@ -2,7 +2,6 @@ package core2sn import ( "github.com/NethermindEth/juno/core" - "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/starknet" "github.com/NethermindEth/juno/utils" ) @@ -20,7 +19,7 @@ func AdaptCompiledClass(coreCompiledClass *core.CompiledClass) starknet.Compiled feederCompiledClass.PythonicHints = coreCompiledClass.PythonicHints feederCompiledClass.CompilerVersion = coreCompiledClass.CompilerVersion feederCompiledClass.Hints = coreCompiledClass.Hints - feederCompiledClass.Prime = "0x" + coreCompiledClass.Prime.Text(felt.Base16) + feederCompiledClass.Prime = utils.ToHex(coreCompiledClass.Prime) feederCompiledClass.BytecodeSegmentLengths = AdaptSegmentLengths(coreCompiledClass.BytecodeSegmentLengths) adapt := func(ep core.CompiledEntryPoint) starknet.CompiledEntryPoint { diff --git a/rpc/executables.go b/rpc/executables.go index 3771eed9a8..f9147642af 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -22,12 +22,13 @@ type EntryPointsByType struct { } type CasmCompiledContractClass struct { - EntryPointsByType EntryPointsByType `json:"entry_points_by_type"` - Prime *felt.Felt `json:"prime"` - CompilerVersion string `json:"compiler_version"` - Bytecode []*felt.Felt `json:"bytecode"` - Hints json.RawMessage `json:"hints"` - BytecodeSegmentLengths []int `json:"bytecode_segment_lengths,omitempty"` + EntryPointsByType EntryPointsByType `json:"entry_points_by_type"` + // can't use felt.Felt here because prime is larger than felt + Prime string `json:"prime"` + CompilerVersion string `json:"compiler_version"` + Bytecode []*felt.Felt `json:"bytecode"` + Hints json.RawMessage `json:"hints"` + BytecodeSegmentLengths []int `json:"bytecode_segment_lengths,omitempty"` } func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass, *jsonrpc.Error) { @@ -63,8 +64,9 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro } var cairo0 struct { - Prime *felt.Felt - Data []*felt.Felt + Prime string `json:"prime"` + CompilerVersion string `json:"compiler_version,omitempty"` + Data []*felt.Felt `json:"data"` } err = json.Unmarshal(program, &cairo0) if err != nil { @@ -87,9 +89,9 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro }, Prime: cairo0.Prime, Bytecode: cairo0.Data, - CompilerVersion: "", - Hints: nil, - BytecodeSegmentLengths: nil, + CompilerVersion: cairo0.CompilerVersion, + Hints: nil, // todo fill this field + BytecodeSegmentLengths: nil, // Cairo 0 classes don't have this field (it was introduced since Sierra 1.5.0) } return result, nil } @@ -109,7 +111,7 @@ func adaptCompiledClass(class *core.CompiledClass) *CasmCompiledContractClass { External: utils.Map(class.External, adaptEntryPoint), L1Handler: utils.Map(class.L1Handler, adaptEntryPoint), }, - Prime: new(felt.Felt).SetBigInt(class.Prime), + Prime: utils.ToHex(class.Prime), CompilerVersion: class.CompilerVersion, Bytecode: class.Bytecode, Hints: class.Hints, diff --git a/rpc/executables_test.go b/rpc/executables_test.go new file mode 100644 index 0000000000..6ce4e6da50 --- /dev/null +++ b/rpc/executables_test.go @@ -0,0 +1,92 @@ +package rpc_test + +import ( + "context" + "encoding/json" + "fmt" + clientFeeder "github.com/NethermindEth/juno/clients/feeder" + "github.com/NethermindEth/juno/core" + "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/db" + "github.com/NethermindEth/juno/jsonrpc" + "github.com/NethermindEth/juno/mocks" + "github.com/NethermindEth/juno/rpc" + "github.com/NethermindEth/juno/starknetdata/feeder" + "github.com/NethermindEth/juno/utils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + "testing" +) + +func TestCompiledCasm(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + rd := mocks.NewMockReader(mockCtrl) + handler := rpc.New(rd, nil, nil, "", nil) + + t.Run("db failure", func(t *testing.T) { + rd.EXPECT().HeadState().Return(nil, nil, fmt.Errorf("error")) + resp, err := handler.CompiledCasm(utils.HexToFelt(t, "0x000")) + assert.Nil(t, resp) + assert.Equal(t, jsonrpc.InternalError, err.Code) + }) + t.Run("class doesn't exist", func(t *testing.T) { + classHash := utils.HexToFelt(t, "0x111") + + mockState := mocks.NewMockStateHistoryReader(mockCtrl) + mockState.EXPECT().Class(classHash).Return(nil, db.ErrKeyNotFound) + rd.EXPECT().HeadState().Return(mockState, nopCloser, nil) + + resp, err := handler.CompiledCasm(classHash) + assert.Nil(t, resp) + assert.Equal(t, jsonrpc.InternalError, err.Code) + }) + t.Run("cairo0", func(t *testing.T) { + classHash := utils.HexToFelt(t, "0x7db5c2c2676c2a5bfc892ee4f596b49514e3056a0eee8ad125870b4fb1dd909") + + cl := clientFeeder.NewTestClient(t, &utils.Sepolia) + fd := feeder.New(cl) + + class, err := fd.Class(context.Background(), classHash) + require.NoError(t, err) + + cairo0, ok := class.(*core.Cairo0Class) + require.True(t, ok) + program, err := utils.Gzip64Decode(cairo0.Program) + require.NoError(t, err) + + // only fields that need to be unmarshaled specified + var cairo0Definition struct { + Data []*felt.Felt `json:"data"` + } + err = json.Unmarshal(program, &cairo0Definition) + require.NoError(t, err) + + mockState := mocks.NewMockStateHistoryReader(mockCtrl) + mockState.EXPECT().Class(classHash).Return(&core.DeclaredClass{Class: class}, nil) + rd.EXPECT().HeadState().Return(mockState, nopCloser, nil) + + resp, rpcErr := handler.CompiledCasm(classHash) + require.Nil(t, rpcErr) + assert.Equal(t, &rpc.CasmCompiledContractClass{ + Prime: "0x800000000000011000000000000000000000000000000000000000000000001", + CompilerVersion: "0.10.3", + EntryPointsByType: rpc.EntryPointsByType{ + Constructor: utils.Map(cairo0.Constructors, adaptEntryPoint), + External: utils.Map(cairo0.Externals, adaptEntryPoint), + L1Handler: utils.Map(cairo0.L1Handlers, adaptEntryPoint), + }, + Bytecode: cairo0Definition.Data, + }, resp) + }) +} + +func adaptEntryPoint(point core.EntryPoint) rpc.CasmEntryPoint { + return rpc.CasmEntryPoint{ + Offset: point.Offset, + Selector: point.Selector, + Builtins: nil, + } +} diff --git a/rpc/handlers.go b/rpc/handlers.go index f0da743528..d96d88f0d2 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -325,6 +325,11 @@ func (h *Handler) Methods() ([]jsonrpc.Method, string) { //nolint: funlen Params: []jsonrpc.Parameter{{Name: "block_id"}}, Handler: h.BlockWithReceipts, }, + { + Name: "starknet_getCompiledCasm", + Params: []jsonrpc.Parameter{{Name: "class_hash"}}, + Handler: h.CompiledCasm, + }, }, "/v0_8" } @@ -483,11 +488,5 @@ func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen Params: []jsonrpc.Parameter{{Name: "block_id"}}, Handler: h.BlockWithReceipts, }, - // temporary, todo change it to 0.8 methods - { - Name: "starknet_getCompiledCasm", - Params: []jsonrpc.Parameter{{Name: "class_hash"}}, - Handler: h.CompiledCasm, - }, }, "/v0_7" } diff --git a/utils/bigint.go b/utils/bigint.go new file mode 100644 index 0000000000..ebf1da91f5 --- /dev/null +++ b/utils/bigint.go @@ -0,0 +1,9 @@ +package utils + +import ( + "math/big" +) + +func ToHex(b *big.Int) string { + return "0x" + b.Text(16) //nolint:mnd +} From 34024d5725e2dca0bd6d8929c0c6652d06e21bbd Mon Sep 17 00:00:00 2001 From: Kirill Date: Tue, 29 Oct 2024 15:24:30 +0400 Subject: [PATCH 5/8] Fix cairo0 hints --- go.mod | 2 ++ go.sum | 10 ++++++++++ rpc/executables.go | 31 ++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 8526f8a8f2..7cde899978 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23.1 require ( github.com/Masterminds/semver/v3 v3.3.0 + github.com/NethermindEth/cairo-vm-go v0.0.0-20241022093807-167daddfd4a4 github.com/bits-and-blooms/bitset v1.14.3 github.com/bits-and-blooms/bloom/v3 v3.7.0 github.com/cockroachdb/pebble v1.1.2 @@ -41,6 +42,7 @@ require ( require ( github.com/DataDog/zstd v1.5.6-0.20230824185856-869dae002e5e // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/alecthomas/participle/v2 v2.0.0 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect diff --git a/go.sum b/go.sum index a48d73a00e..e4ec798c87 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,16 @@ github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+ github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/NethermindEth/cairo-vm-go v0.0.0-20241022093807-167daddfd4a4 h1:sAdffkxtfPBOGjxhyHUC4q0yUQJ/0ut8Rci+hctn/M4= +github.com/NethermindEth/cairo-vm-go v0.0.0-20241022093807-167daddfd4a4/go.mod h1:U1ls2WSMF5cxRI7jjm4G7mnS8f/XiFafMHCikN+tTQw= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g= +github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -228,6 +236,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= diff --git a/rpc/executables.go b/rpc/executables.go index f9147642af..236d070913 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -3,6 +3,8 @@ package rpc import ( "encoding/json" + hintRunnerZero "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/zero" + "github.com/NethermindEth/cairo-vm-go/pkg/parsers/zero" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/jsonrpc" @@ -63,16 +65,31 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro return nil, err } - var cairo0 struct { - Prime string `json:"prime"` - CompilerVersion string `json:"compiler_version,omitempty"` - Data []*felt.Felt `json:"data"` - } + var cairo0 zero.ZeroProgram err = json.Unmarshal(program, &cairo0) if err != nil { return nil, err } + var bytecode []*felt.Felt + for _, str := range cairo0.Data { + f, err := new(felt.Felt).SetString(str) + if err != nil { + return nil, err + } + bytecode = append(bytecode, f) + } + + hints, err := hintRunnerZero.GetZeroHints(&cairo0) + if err != nil { + return nil, err + } + + rawHints, err := json.Marshal(hints) + if err != nil { + return nil, err + } + adaptEntryPoint := func(ep core.EntryPoint) CasmEntryPoint { return CasmEntryPoint{ Offset: ep.Offset, @@ -88,9 +105,9 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro L1Handler: utils.Map(class.L1Handlers, adaptEntryPoint), }, Prime: cairo0.Prime, - Bytecode: cairo0.Data, + Bytecode: bytecode, CompilerVersion: cairo0.CompilerVersion, - Hints: nil, // todo fill this field + Hints: json.RawMessage(rawHints), BytecodeSegmentLengths: nil, // Cairo 0 classes don't have this field (it was introduced since Sierra 1.5.0) } return result, nil From 60d24434633f80664de11f8a2033b03047d69b89 Mon Sep 17 00:00:00 2001 From: Kirill Date: Tue, 29 Oct 2024 16:58:34 +0400 Subject: [PATCH 6/8] Add utils.OrderMap and use it in starknet_getCompiledCasm --- rpc/executables.go | 6 +++++- utils/ordered_map.go | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 utils/ordered_map.go diff --git a/rpc/executables.go b/rpc/executables.go index 236d070913..f243836450 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -80,11 +80,15 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro bytecode = append(bytecode, f) } - hints, err := hintRunnerZero.GetZeroHints(&cairo0) + classHints, err := hintRunnerZero.GetZeroHints(&cairo0) if err != nil { return nil, err } + var hints [][2]any // slice of 2-element tuples where first value is pc, and second value is slice of hints + for pc, hintItems := range utils.OrderMap(classHints) { + hints = append(hints, [2]any{pc, hintItems}) + } rawHints, err := json.Marshal(hints) if err != nil { return nil, err diff --git a/utils/ordered_map.go b/utils/ordered_map.go new file mode 100644 index 0000000000..9019aa1537 --- /dev/null +++ b/utils/ordered_map.go @@ -0,0 +1,26 @@ +package utils + +import ( + "cmp" + "iter" + "slices" +) + +func OrderMap[K cmp.Ordered, T any](m map[K]T) iter.Seq2[K, T] { + // 1. collect keys + keys := make([]K, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + + // 2. sort them + slices.Sort(keys) + return func(yield func(K, T) bool) { + // 3. because keys are sorted now, we can iterate over them in order + for _, k := range keys { + if !yield(k, m[k]) { + return + } + } + } +} From fbec78feeb10a0d6681190c8e2488fdc137f5835 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 30 Oct 2024 01:32:19 +0400 Subject: [PATCH 7/8] Review fixes --- rpc/{executables.go => compiled_casm.go} | 9 ++++++- ...cutables_test.go => compiled_casm_test.go} | 3 ++- utils/maps.go | 22 ++++++++++++++++ utils/maps_test.go | 20 ++++++++++++++ utils/ordered_map.go | 26 ------------------- 5 files changed, 52 insertions(+), 28 deletions(-) rename rpc/{executables.go => compiled_casm.go} (93%) rename rpc/{executables_test.go => compiled_casm_test.go} (99%) create mode 100644 utils/maps_test.go delete mode 100644 utils/ordered_map.go diff --git a/rpc/executables.go b/rpc/compiled_casm.go similarity index 93% rename from rpc/executables.go rename to rpc/compiled_casm.go index f243836450..2924416085 100644 --- a/rpc/executables.go +++ b/rpc/compiled_casm.go @@ -2,11 +2,13 @@ package rpc import ( "encoding/json" + "errors" hintRunnerZero "github.com/NethermindEth/cairo-vm-go/pkg/hintrunner/zero" "github.com/NethermindEth/cairo-vm-go/pkg/parsers/zero" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/jsonrpc" "github.com/NethermindEth/juno/utils" ) @@ -23,6 +25,8 @@ type EntryPointsByType struct { L1Handler []CasmEntryPoint `json:"L1_HANDLER"` } +// CasmCompiledContractClass follows this specification: +// https://github.com/starkware-libs/starknet-specs/blob/v0.8.0-rc0/api/starknet_executables.json#L45 type CasmCompiledContractClass struct { EntryPointsByType EntryPointsByType `json:"entry_points_by_type"` // can't use felt.Felt here because prime is larger than felt @@ -42,6 +46,9 @@ func (h *Handler) CompiledCasm(classHash *felt.Felt) (*CasmCompiledContractClass declaredClass, err := state.Class(classHash) if err != nil { + if errors.Is(err, db.ErrKeyNotFound) { + return nil, ErrClassHashNotFound + } return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error()) } @@ -86,7 +93,7 @@ func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, erro } var hints [][2]any // slice of 2-element tuples where first value is pc, and second value is slice of hints - for pc, hintItems := range utils.OrderMap(classHints) { + for pc, hintItems := range utils.SortedMap(classHints) { hints = append(hints, [2]any{pc, hintItems}) } rawHints, err := json.Marshal(hints) diff --git a/rpc/executables_test.go b/rpc/compiled_casm_test.go similarity index 99% rename from rpc/executables_test.go rename to rpc/compiled_casm_test.go index 6ce4e6da50..a1afb81ad4 100644 --- a/rpc/executables_test.go +++ b/rpc/compiled_casm_test.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + "testing" + clientFeeder "github.com/NethermindEth/juno/clients/feeder" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" @@ -16,7 +18,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" - "testing" ) func TestCompiledCasm(t *testing.T) { diff --git a/utils/maps.go b/utils/maps.go index 886929ab93..6c78515267 100644 --- a/utils/maps.go +++ b/utils/maps.go @@ -1,5 +1,12 @@ package utils +import ( + "cmp" + "iter" + "maps" + "slices" +) + func ToMap[T any, K comparable, V any](sl []T, f func(T) (K, V)) map[K]V { m := make(map[K]V, len(sl)) for _, item := range sl { @@ -22,3 +29,18 @@ func ToSlice[K comparable, V any, T any](m map[K]V, f func(K, V) T) []T { return sl } + +func SortedMap[K cmp.Ordered, T any](m map[K]T) iter.Seq2[K, T] { + // 1. collect keys + keys := maps.Keys(m) + // 2. sort them + sortedKeys := slices.Sorted(keys) + return func(yield func(K, T) bool) { + // 3. pass key-value pairs in sorted order + for _, k := range sortedKeys { + if !yield(k, m[k]) { + return + } + } + } +} diff --git a/utils/maps_test.go b/utils/maps_test.go new file mode 100644 index 0000000000..3ce36d0647 --- /dev/null +++ b/utils/maps_test.go @@ -0,0 +1,20 @@ +package utils + +import ( + "slices" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSortedMap(t *testing.T) { + m := map[int]string{3: "three", 1: "one", 4: "four", 2: "two", 0: "zero"} + + var keys []int + for k, v := range SortedMap(m) { + keys = append(keys, k) + assert.Equal(t, m[k], v) + } + assert.Len(t, keys, len(m)) + assert.True(t, slices.IsSorted(keys)) +} diff --git a/utils/ordered_map.go b/utils/ordered_map.go deleted file mode 100644 index 9019aa1537..0000000000 --- a/utils/ordered_map.go +++ /dev/null @@ -1,26 +0,0 @@ -package utils - -import ( - "cmp" - "iter" - "slices" -) - -func OrderMap[K cmp.Ordered, T any](m map[K]T) iter.Seq2[K, T] { - // 1. collect keys - keys := make([]K, 0, len(m)) - for k := range m { - keys = append(keys, k) - } - - // 2. sort them - slices.Sort(keys) - return func(yield func(K, T) bool) { - // 3. because keys are sorted now, we can iterate over them in order - for _, k := range keys { - if !yield(k, m[k]) { - return - } - } - } -} From dcd80d5afeca66740f1ae99cf11eb9bf9d17d436 Mon Sep 17 00:00:00 2001 From: Kirill Date: Wed, 30 Oct 2024 02:16:40 +0400 Subject: [PATCH 8/8] Fix tests and linter --- ...d346fc029f977167d5b1b2b59f69a7dacbfc8.json | 1063 +++++++++++++++++ rpc/compiled_casm_test.go | 5 +- 2 files changed, 1066 insertions(+), 2 deletions(-) create mode 100644 clients/feeder/testdata/sepolia/class/0x5f18f9cdc05da87f04e8e7685bd346fc029f977167d5b1b2b59f69a7dacbfc8.json diff --git a/clients/feeder/testdata/sepolia/class/0x5f18f9cdc05da87f04e8e7685bd346fc029f977167d5b1b2b59f69a7dacbfc8.json b/clients/feeder/testdata/sepolia/class/0x5f18f9cdc05da87f04e8e7685bd346fc029f977167d5b1b2b59f69a7dacbfc8.json new file mode 100644 index 0000000000..668bc8f7ea --- /dev/null +++ b/clients/feeder/testdata/sepolia/class/0x5f18f9cdc05da87f04e8e7685bd346fc029f977167d5b1b2b59f69a7dacbfc8.json @@ -0,0 +1,1063 @@ +{ + "entry_points_by_type": { + "CONSTRUCTOR": [], + "EXTERNAL": [ + { + "selector": "0x35a8bb8492337e79bdc674d6f31ac448f8017e26cc7bfe3144fb5d886fe5369", + "offset": 11 + } + ], + "L1_HANDLER": [] + }, + "program": { + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "data": [ + "0x482a7ffd7ffc8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x4003800080007ffc", + "0x4826800180008000", + "0x1", + "0x480a7ffd7fff8000", + "0x4828800080007ffe", + "0x480a80007fff8000", + "0x208b7fff7fff7ffe", + "0x482680017ffd8000", + "0x2", + "0x402a7ffd7ffc7fff", + "0x480280007ffd8000", + "0x480280017ffd8000", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff1", + "0x480280017ffb8000", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffff0", + "0x480280007ffb8000", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x48127ffc7fff8000", + "0x208b7fff7fff7ffe" + ], + "builtins": [ + "range_check" + ], + "hints": { + "2": [ + { + "code": "memory[ap] = segments.add()", + "accessible_scopes": [ + "__main__", + "__main__", + "__wrappers__", + "__wrappers__.add_encode_return" + ], + "flow_tracking_data": { + "ap_tracking": { + "group": 1, + "offset": 0 + }, + "reference_ids": {} + } + } + ] + }, + "compiler_version": "0.10.3", + "main_scope": "__main__", + "identifiers": { + "starkware.cairo.common.ec_point.EcPoint": { + "full_name": "starkware.cairo.common.ec_point.EcPoint", + "members": { + "x": { + "offset": 0, + "cairo_type": "felt" + }, + "y": { + "offset": 1, + "cairo_type": "felt" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.cairo.common.keccak_state.KeccakBuiltinState": { + "full_name": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "members": { + "s0": { + "offset": 0, + "cairo_type": "felt" + }, + "s1": { + "offset": 1, + "cairo_type": "felt" + }, + "s2": { + "offset": 2, + "cairo_type": "felt" + }, + "s3": { + "offset": 3, + "cairo_type": "felt" + }, + "s4": { + "offset": 4, + "cairo_type": "felt" + }, + "s5": { + "offset": 5, + "cairo_type": "felt" + }, + "s6": { + "offset": 6, + "cairo_type": "felt" + }, + "s7": { + "offset": 7, + "cairo_type": "felt" + } + }, + "size": 8, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.EcPoint": { + "destination": "starkware.cairo.common.ec_point.EcPoint", + "type": "alias" + }, + "starkware.cairo.common.cairo_builtins.KeccakBuiltinState": { + "destination": "starkware.cairo.common.keccak_state.KeccakBuiltinState", + "type": "alias" + }, + "starkware.cairo.common.cairo_builtins.HashBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.HashBuiltin", + "members": { + "x": { + "offset": 0, + "cairo_type": "felt" + }, + "y": { + "offset": 1, + "cairo_type": "felt" + }, + "result": { + "offset": 2, + "cairo_type": "felt" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.SignatureBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.SignatureBuiltin", + "members": { + "pub_key": { + "offset": 0, + "cairo_type": "felt" + }, + "message": { + "offset": 1, + "cairo_type": "felt" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.BitwiseBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.BitwiseBuiltin", + "members": { + "x": { + "offset": 0, + "cairo_type": "felt" + }, + "y": { + "offset": 1, + "cairo_type": "felt" + }, + "x_and_y": { + "offset": 2, + "cairo_type": "felt" + }, + "x_xor_y": { + "offset": 3, + "cairo_type": "felt" + }, + "x_or_y": { + "offset": 4, + "cairo_type": "felt" + } + }, + "size": 5, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.EcOpBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.EcOpBuiltin", + "members": { + "p": { + "offset": 0, + "cairo_type": "starkware.cairo.common.ec_point.EcPoint" + }, + "q": { + "offset": 2, + "cairo_type": "starkware.cairo.common.ec_point.EcPoint" + }, + "m": { + "offset": 4, + "cairo_type": "felt" + }, + "r": { + "offset": 5, + "cairo_type": "starkware.cairo.common.ec_point.EcPoint" + } + }, + "size": 7, + "type": "struct" + }, + "starkware.cairo.common.cairo_builtins.KeccakBuiltin": { + "full_name": "starkware.cairo.common.cairo_builtins.KeccakBuiltin", + "members": { + "input": { + "offset": 0, + "cairo_type": "starkware.cairo.common.keccak_state.KeccakBuiltinState" + }, + "output": { + "offset": 8, + "cairo_type": "starkware.cairo.common.keccak_state.KeccakBuiltinState" + } + }, + "size": 16, + "type": "struct" + }, + "starkware.cairo.common.hash.HashBuiltin": { + "destination": "starkware.cairo.common.cairo_builtins.HashBuiltin", + "type": "alias" + }, + "starkware.cairo.common.bool.FALSE": { + "value": 0, + "type": "const" + }, + "starkware.cairo.common.bool.TRUE": { + "value": 1, + "type": "const" + }, + "starkware.cairo.common.math.FALSE": { + "destination": "starkware.cairo.common.bool.FALSE", + "type": "alias" + }, + "starkware.cairo.common.math.TRUE": { + "destination": "starkware.cairo.common.bool.TRUE", + "type": "alias" + }, + "starkware.starknet.common.storage.assert_250_bit": { + "destination": "starkware.cairo.common.math.assert_250_bit", + "type": "alias" + }, + "starkware.starknet.common.storage.MAX_STORAGE_ITEM_SIZE": { + "value": 256, + "type": "const" + }, + "starkware.starknet.common.storage.ADDR_BOUND": { + "value": -1.0671072950157357e+59, + "type": "const" + }, + "starkware.cairo.common.dict_access.DictAccess": { + "full_name": "starkware.cairo.common.dict_access.DictAccess", + "members": { + "key": { + "offset": 0, + "cairo_type": "felt" + }, + "prev_value": { + "offset": 1, + "cairo_type": "felt" + }, + "new_value": { + "offset": 2, + "cairo_type": "felt" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.starknet.common.syscalls.DictAccess": { + "destination": "starkware.cairo.common.dict_access.DictAccess", + "type": "alias" + }, + "starkware.starknet.common.syscalls.SEND_MESSAGE_TO_L1_SELECTOR": { + "value": 4.3301790876830345e+35, + "type": "const" + }, + "starkware.starknet.common.syscalls.SendMessageToL1SysCall": { + "full_name": "starkware.starknet.common.syscalls.SendMessageToL1SysCall", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "to_address": { + "offset": 1, + "cairo_type": "felt" + }, + "payload_size": { + "offset": 2, + "cairo_type": "felt" + }, + "payload_ptr": { + "offset": 3, + "cairo_type": "felt*" + } + }, + "size": 4, + "type": "struct" + }, + "starkware.starknet.common.syscalls.CALL_CONTRACT_SELECTOR": { + "value": 2.0853273475220474e+28, + "type": "const" + }, + "starkware.starknet.common.syscalls.DELEGATE_CALL_SELECTOR": { + "value": 2.1167594061783206e+28, + "type": "const" + }, + "starkware.starknet.common.syscalls.DELEGATE_L1_HANDLER_SELECTOR": { + "value": 2.3274015802972845e+40, + "type": "const" + }, + "starkware.starknet.common.syscalls.CallContractRequest": { + "full_name": "starkware.starknet.common.syscalls.CallContractRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "contract_address": { + "offset": 1, + "cairo_type": "felt" + }, + "function_selector": { + "offset": 2, + "cairo_type": "felt" + }, + "calldata_size": { + "offset": 3, + "cairo_type": "felt" + }, + "calldata": { + "offset": 4, + "cairo_type": "felt*" + } + }, + "size": 5, + "type": "struct" + }, + "starkware.starknet.common.syscalls.CallContractResponse": { + "full_name": "starkware.starknet.common.syscalls.CallContractResponse", + "members": { + "retdata_size": { + "offset": 0, + "cairo_type": "felt" + }, + "retdata": { + "offset": 1, + "cairo_type": "felt*" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.CallContract": { + "full_name": "starkware.starknet.common.syscalls.CallContract", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.CallContractRequest" + }, + "response": { + "offset": 5, + "cairo_type": "starkware.starknet.common.syscalls.CallContractResponse" + } + }, + "size": 7, + "type": "struct" + }, + "starkware.starknet.common.syscalls.LIBRARY_CALL_SELECTOR": { + "value": 9.2376026794327e+25, + "type": "const" + }, + "starkware.starknet.common.syscalls.LIBRARY_CALL_L1_HANDLER_SELECTOR": { + "value": 4.362334527541981e+47, + "type": "const" + }, + "starkware.starknet.common.syscalls.LibraryCallRequest": { + "full_name": "starkware.starknet.common.syscalls.LibraryCallRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "class_hash": { + "offset": 1, + "cairo_type": "felt" + }, + "function_selector": { + "offset": 2, + "cairo_type": "felt" + }, + "calldata_size": { + "offset": 3, + "cairo_type": "felt" + }, + "calldata": { + "offset": 4, + "cairo_type": "felt*" + } + }, + "size": 5, + "type": "struct" + }, + "starkware.starknet.common.syscalls.LibraryCall": { + "full_name": "starkware.starknet.common.syscalls.LibraryCall", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.LibraryCallRequest" + }, + "response": { + "offset": 5, + "cairo_type": "starkware.starknet.common.syscalls.CallContractResponse" + } + }, + "size": 7, + "type": "struct" + }, + "starkware.starknet.common.syscalls.DEPLOY_SELECTOR": { + "value": 75202468540281, + "type": "const" + }, + "starkware.starknet.common.syscalls.DeployRequest": { + "full_name": "starkware.starknet.common.syscalls.DeployRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "class_hash": { + "offset": 1, + "cairo_type": "felt" + }, + "contract_address_salt": { + "offset": 2, + "cairo_type": "felt" + }, + "constructor_calldata_size": { + "offset": 3, + "cairo_type": "felt" + }, + "constructor_calldata": { + "offset": 4, + "cairo_type": "felt*" + }, + "deploy_from_zero": { + "offset": 5, + "cairo_type": "felt" + } + }, + "size": 6, + "type": "struct" + }, + "starkware.starknet.common.syscalls.DeployResponse": { + "full_name": "starkware.starknet.common.syscalls.DeployResponse", + "members": { + "contract_address": { + "offset": 0, + "cairo_type": "felt" + }, + "constructor_retdata_size": { + "offset": 1, + "cairo_type": "felt" + }, + "constructor_retdata": { + "offset": 2, + "cairo_type": "felt*" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.starknet.common.syscalls.Deploy": { + "full_name": "starkware.starknet.common.syscalls.Deploy", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.DeployRequest" + }, + "response": { + "offset": 6, + "cairo_type": "starkware.starknet.common.syscalls.DeployResponse" + } + }, + "size": 9, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_CALLER_ADDRESS_SELECTOR": { + "value": 9.490196778139308e+37, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetCallerAddressRequest": { + "full_name": "starkware.starknet.common.syscalls.GetCallerAddressRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetCallerAddressResponse": { + "full_name": "starkware.starknet.common.syscalls.GetCallerAddressResponse", + "members": { + "caller_address": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetCallerAddress": { + "full_name": "starkware.starknet.common.syscalls.GetCallerAddress", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetCallerAddressRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetCallerAddressResponse" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_SEQUENCER_ADDRESS_SELECTOR": { + "value": 1.5921908335819916e+45, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetSequencerAddressRequest": { + "full_name": "starkware.starknet.common.syscalls.GetSequencerAddressRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetSequencerAddressResponse": { + "full_name": "starkware.starknet.common.syscalls.GetSequencerAddressResponse", + "members": { + "sequencer_address": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetSequencerAddress": { + "full_name": "starkware.starknet.common.syscalls.GetSequencerAddress", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetSequencerAddressRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetSequencerAddressResponse" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_BLOCK_NUMBER_SELECTOR": { + "value": 1.448089106835523e+33, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetBlockNumberRequest": { + "full_name": "starkware.starknet.common.syscalls.GetBlockNumberRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetBlockNumberResponse": { + "full_name": "starkware.starknet.common.syscalls.GetBlockNumberResponse", + "members": { + "block_number": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetBlockNumber": { + "full_name": "starkware.starknet.common.syscalls.GetBlockNumber", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetBlockNumberRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetBlockNumberResponse" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_CONTRACT_ADDRESS_SELECTOR": { + "value": 6.219495360805491e+42, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetContractAddressRequest": { + "full_name": "starkware.starknet.common.syscalls.GetContractAddressRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetContractAddressResponse": { + "full_name": "starkware.starknet.common.syscalls.GetContractAddressResponse", + "members": { + "contract_address": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetContractAddress": { + "full_name": "starkware.starknet.common.syscalls.GetContractAddress", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetContractAddressRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetContractAddressResponse" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_BLOCK_TIMESTAMP_SELECTOR": { + "value": 2.4294903732626647e+40, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetBlockTimestampRequest": { + "full_name": "starkware.starknet.common.syscalls.GetBlockTimestampRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetBlockTimestampResponse": { + "full_name": "starkware.starknet.common.syscalls.GetBlockTimestampResponse", + "members": { + "block_timestamp": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetBlockTimestamp": { + "full_name": "starkware.starknet.common.syscalls.GetBlockTimestamp", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetBlockTimestampRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetBlockTimestampResponse" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_TX_SIGNATURE_SELECTOR": { + "value": 1.44808912865234e+33, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetTxSignatureRequest": { + "full_name": "starkware.starknet.common.syscalls.GetTxSignatureRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetTxSignatureResponse": { + "full_name": "starkware.starknet.common.syscalls.GetTxSignatureResponse", + "members": { + "signature_len": { + "offset": 0, + "cairo_type": "felt" + }, + "signature": { + "offset": 1, + "cairo_type": "felt*" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetTxSignature": { + "full_name": "starkware.starknet.common.syscalls.GetTxSignature", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetTxSignatureRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetTxSignatureResponse" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.starknet.common.syscalls.STORAGE_READ_SELECTOR": { + "value": 1.0089069337060175e+26, + "type": "const" + }, + "starkware.starknet.common.syscalls.StorageReadRequest": { + "full_name": "starkware.starknet.common.syscalls.StorageReadRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "address": { + "offset": 1, + "cairo_type": "felt" + } + }, + "size": 2, + "type": "struct" + }, + "starkware.starknet.common.syscalls.StorageReadResponse": { + "full_name": "starkware.starknet.common.syscalls.StorageReadResponse", + "members": { + "value": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.StorageRead": { + "full_name": "starkware.starknet.common.syscalls.StorageRead", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.StorageReadRequest" + }, + "response": { + "offset": 2, + "cairo_type": "starkware.starknet.common.syscalls.StorageReadResponse" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.starknet.common.syscalls.STORAGE_WRITE_SELECTOR": { + "value": 2.582801750287405e+28, + "type": "const" + }, + "starkware.starknet.common.syscalls.StorageWrite": { + "full_name": "starkware.starknet.common.syscalls.StorageWrite", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "address": { + "offset": 1, + "cairo_type": "felt" + }, + "value": { + "offset": 2, + "cairo_type": "felt" + } + }, + "size": 3, + "type": "struct" + }, + "starkware.starknet.common.syscalls.EMIT_EVENT_SELECTOR": { + "value": 1.2807093015503357e+21, + "type": "const" + }, + "starkware.starknet.common.syscalls.EmitEvent": { + "full_name": "starkware.starknet.common.syscalls.EmitEvent", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + }, + "keys_len": { + "offset": 1, + "cairo_type": "felt" + }, + "keys": { + "offset": 2, + "cairo_type": "felt*" + }, + "data_len": { + "offset": 3, + "cairo_type": "felt" + }, + "data": { + "offset": 4, + "cairo_type": "felt*" + } + }, + "size": 5, + "type": "struct" + }, + "starkware.starknet.common.syscalls.TxInfo": { + "full_name": "starkware.starknet.common.syscalls.TxInfo", + "members": { + "version": { + "offset": 0, + "cairo_type": "felt" + }, + "account_contract_address": { + "offset": 1, + "cairo_type": "felt" + }, + "max_fee": { + "offset": 2, + "cairo_type": "felt" + }, + "signature_len": { + "offset": 3, + "cairo_type": "felt" + }, + "signature": { + "offset": 4, + "cairo_type": "felt*" + }, + "transaction_hash": { + "offset": 5, + "cairo_type": "felt" + }, + "chain_id": { + "offset": 6, + "cairo_type": "felt" + }, + "nonce": { + "offset": 7, + "cairo_type": "felt" + } + }, + "size": 8, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GET_TX_INFO_SELECTOR": { + "value": 1.3170293902041122e+21, + "type": "const" + }, + "starkware.starknet.common.syscalls.GetTxInfoRequest": { + "full_name": "starkware.starknet.common.syscalls.GetTxInfoRequest", + "members": { + "selector": { + "offset": 0, + "cairo_type": "felt" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetTxInfoResponse": { + "full_name": "starkware.starknet.common.syscalls.GetTxInfoResponse", + "members": { + "tx_info": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.TxInfo*" + } + }, + "size": 1, + "type": "struct" + }, + "starkware.starknet.common.syscalls.GetTxInfo": { + "full_name": "starkware.starknet.common.syscalls.GetTxInfo", + "members": { + "request": { + "offset": 0, + "cairo_type": "starkware.starknet.common.syscalls.GetTxInfoRequest" + }, + "response": { + "offset": 1, + "cairo_type": "starkware.starknet.common.syscalls.GetTxInfoResponse" + } + }, + "size": 2, + "type": "struct" + }, + "__main__.add": { + "pc": 0, + "decorators": [ + "view" + ], + "type": "function" + }, + "__main__.add.Args": { + "full_name": "__main__.add.Args", + "members": { + "x": { + "offset": 0, + "cairo_type": "felt" + }, + "y": { + "offset": 1, + "cairo_type": "felt" + } + }, + "size": 2, + "type": "struct" + }, + "__main__.add.ImplicitArgs": { + "full_name": "__main__.add.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__main__.add.Return": { + "cairo_type": "(res: felt)", + "type": "type_definition" + }, + "__main__.add.SIZEOF_LOCALS": { + "value": 0, + "type": "const" + }, + "__wrappers__.add.__wrapped_func": { + "destination": "__main__.add", + "type": "alias" + }, + "__wrappers__.add_encode_return.memcpy": { + "destination": "starkware.cairo.common.memcpy.memcpy", + "type": "alias" + }, + "__wrappers__.add_encode_return": { + "pc": 2, + "decorators": [], + "type": "function" + }, + "__wrappers__.add_encode_return.Args": { + "full_name": "__wrappers__.add_encode_return.Args", + "members": { + "ret_value": { + "offset": 0, + "cairo_type": "(res: felt)" + }, + "range_check_ptr": { + "offset": 1, + "cairo_type": "felt" + } + }, + "size": 2, + "type": "struct" + }, + "__wrappers__.add_encode_return.ImplicitArgs": { + "full_name": "__wrappers__.add_encode_return.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.add_encode_return.Return": { + "cairo_type": "(range_check_ptr: felt, data_len: felt, data: felt*)", + "type": "type_definition" + }, + "__wrappers__.add_encode_return.SIZEOF_LOCALS": { + "value": 1, + "type": "const" + }, + "__wrappers__.add": { + "pc": 11, + "decorators": [ + "view" + ], + "type": "function" + }, + "__wrappers__.add.Args": { + "full_name": "__wrappers__.add.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.add.ImplicitArgs": { + "full_name": "__wrappers__.add.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.add.Return": { + "cairo_type": "(syscall_ptr: felt, range_check_ptr: felt, size: felt, retdata: felt*)", + "type": "type_definition" + }, + "__wrappers__.add.SIZEOF_LOCALS": { + "value": 0, + "type": "const" + } + }, + "reference_manager": { + "references": [] + }, + "attributes": [], + "debug_info": null + }, + "abi": [ + { + "inputs": [ + { + "name": "x", + "type": "felt" + }, + { + "name": "y", + "type": "felt" + } + ], + "name": "add", + "outputs": [ + { + "name": "res", + "type": "felt" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/rpc/compiled_casm_test.go b/rpc/compiled_casm_test.go index a1afb81ad4..19f0d44bf6 100644 --- a/rpc/compiled_casm_test.go +++ b/rpc/compiled_casm_test.go @@ -42,10 +42,10 @@ func TestCompiledCasm(t *testing.T) { resp, err := handler.CompiledCasm(classHash) assert.Nil(t, resp) - assert.Equal(t, jsonrpc.InternalError, err.Code) + assert.Equal(t, rpc.ErrClassHashNotFound, err) }) t.Run("cairo0", func(t *testing.T) { - classHash := utils.HexToFelt(t, "0x7db5c2c2676c2a5bfc892ee4f596b49514e3056a0eee8ad125870b4fb1dd909") + classHash := utils.HexToFelt(t, "0x5f18f9cdc05da87f04e8e7685bd346fc029f977167d5b1b2b59f69a7dacbfc8") cl := clientFeeder.NewTestClient(t, &utils.Sepolia) fd := feeder.New(cl) @@ -79,6 +79,7 @@ func TestCompiledCasm(t *testing.T) { External: utils.Map(cairo0.Externals, adaptEntryPoint), L1Handler: utils.Map(cairo0.L1Handlers, adaptEntryPoint), }, + Hints: json.RawMessage(`[[2,[{"Dst":0}]]]`), Bytecode: cairo0Definition.Data, }, resp) })