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 starknet_getCompiledCasm #2204

Merged
merged 10 commits into from
Oct 30, 2024
132 changes: 132 additions & 0 deletions rpc/executables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package rpc

import (
"encoding/json"

"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/jsonrpc"
"github.com/NethermindEth/juno/utils"
)

type CasmEntryPoint struct {
kirugan marked this conversation as resolved.
Show resolved Hide resolved
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) {
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 := state.Class(classHash)
kirugan marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error())
}

Check warning on line 43 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L33-L43

Added lines #L33 - L43 were not covered by tests

switch class := declaredClass.Class.(type) {
case *core.Cairo0Class:
resp, err := adaptCairo0Class(class)
if err != nil {
return nil, jsonrpc.Err(jsonrpc.InternalError, err.Error())
}
return resp, nil
case *core.Cairo1Class:
return adaptCompiledClass(class.Compiled), nil

Check warning on line 53 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L45-L53

Added lines #L45 - L53 were not covered by tests
}

return nil, jsonrpc.Err(jsonrpc.InternalError, "unsupported class type")

Check warning on line 56 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L56

Added line #L56 was not covered by tests
}

func adaptCairo0Class(class *core.Cairo0Class) (*CasmCompiledContractClass, error) {
program, err := utils.Gzip64Decode(class.Program)
if err != nil {
return nil, err
}

Check warning on line 63 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L59-L63

Added lines #L59 - L63 were not covered by tests

var cairo0 struct {
Prime *felt.Felt
Data []*felt.Felt
}
err = json.Unmarshal(program, &cairo0)
if err != nil {
return nil, err
}

Check warning on line 72 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L65-L72

Added lines #L65 - L72 were not covered by tests

adaptEntryPoint := func(ep core.EntryPoint) CasmEntryPoint {
return CasmEntryPoint{
Offset: ep.Offset,
Selector: ep.Selector,
Builtins: nil,
}
}

Check warning on line 80 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L74-L80

Added lines #L74 - L80 were not covered by tests

result := &CasmCompiledContractClass{
EntryPointsByType: EntryPointsByType{
Constructor: utils.Map(class.Constructors, adaptEntryPoint),
kirugan marked this conversation as resolved.
Show resolved Hide resolved
External: utils.Map(class.Externals, adaptEntryPoint),
L1Handler: utils.Map(class.L1Handlers, adaptEntryPoint),
},
Prime: cairo0.Prime,
Bytecode: cairo0.Data,
CompilerVersion: "",
Hints: nil,
BytecodeSegmentLengths: nil,
kirugan marked this conversation as resolved.
Show resolved Hide resolved
}
return result, nil

Check warning on line 94 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L82-L94

Added lines #L82 - L94 were not covered by tests
}

func adaptCompiledClass(class *core.CompiledClass) *CasmCompiledContractClass {
kirugan marked this conversation as resolved.
Show resolved Hide resolved
adaptEntryPoint := func(ep core.CompiledEntryPoint) CasmEntryPoint {
return CasmEntryPoint{
Offset: new(felt.Felt).SetUint64(ep.Offset),
Selector: ep.Selector,
Builtins: ep.Builtins,
}
}

Check warning on line 104 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L97-L104

Added lines #L97 - L104 were not covered by tests

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: collectSegmentLengths(class.BytecodeSegmentLengths),
}
return result

Check warning on line 118 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L106-L118

Added lines #L106 - L118 were not covered by tests
}

func collectSegmentLengths(segmentLengths core.SegmentLengths) []int {
if len(segmentLengths.Children) == 0 {
return []int{int(segmentLengths.Length)}
}

Check warning on line 124 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L121-L124

Added lines #L121 - L124 were not covered by tests

var result []int
for _, child := range segmentLengths.Children {
result = append(result, collectSegmentLengths(child)...)
}

Check warning on line 129 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L126-L129

Added lines #L126 - L129 were not covered by tests

return result

Check warning on line 131 in rpc/executables.go

View check run for this annotation

Codecov / codecov/patch

rpc/executables.go#L131

Added line #L131 was not covered by tests
}
10 changes: 8 additions & 2 deletions rpc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -483,5 +483,11 @@ func (h *Handler) MethodsV0_7() ([]jsonrpc.Method, string) { //nolint: funlen, d
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"
}