From d232bd9128d0d99688bb80561b027b22b37c7ecc Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Tue, 29 Oct 2024 01:52:16 -0300 Subject: [PATCH 1/6] Creates new types --- rpc/executables.go | 24 ++++ rpc/types_contract.go | 4 +- rpc/types_executables.go | 300 +++++++++++++++++++++++++++++++++++++++ utils/data.go | 20 ++- 4 files changed, 345 insertions(+), 3 deletions(-) create mode 100644 rpc/executables.go create mode 100644 rpc/types_executables.go diff --git a/rpc/executables.go b/rpc/executables.go new file mode 100644 index 00000000..5e6cd7b9 --- /dev/null +++ b/rpc/executables.go @@ -0,0 +1,24 @@ +package rpc + +import ( + "context" + + "github.com/NethermindEth/juno/core/felt" +) + +// Get the contract class definition in the given block associated with the given hash +// +// Parameters: +// - ctx: The context.Context used for the request +// - classHash: The hash of the contract class whose CASM will be returned +// Returns: +// - *felt.Felt: The compiled contract class +// - error: An error if any occurred during the execution +func (provider *Provider) CompiledCasm(ctx context.Context, classHash *felt.Felt) (*felt.Felt, error) { + var result *felt.Felt + if err := do(ctx, provider.c, "starknet_getCompiledCasm", &result, classHash); err != nil { + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) + } + return result, nil +} diff --git a/rpc/types_contract.go b/rpc/types_contract.go index d7ea97b7..affc336c 100644 --- a/rpc/types_contract.go +++ b/rpc/types_contract.go @@ -69,7 +69,7 @@ type ContractClass struct { // The version of the contract class object. Currently, the Starknet OS supports version 0.1.0 ContractClassVersion string `json:"contract_class_version"` - EntryPointsByType EntryPointsByType `json:"entry_points_by_type"` + EntryPointsByType SierraEntryPointsByType `json:"entry_points_by_type"` ABI string `json:"abi,omitempty"` } @@ -285,7 +285,7 @@ type SierraEntryPoint struct { Selector *felt.Felt `json:"selector"` } -type EntryPointsByType struct { +type SierraEntryPointsByType struct { Constructor []SierraEntryPoint `json:"CONSTRUCTOR"` External []SierraEntryPoint `json:"EXTERNAL"` L1Handler []SierraEntryPoint `json:"L1_HANDLER"` diff --git a/rpc/types_executables.go b/rpc/types_executables.go new file mode 100644 index 00000000..eea0248d --- /dev/null +++ b/rpc/types_executables.go @@ -0,0 +1,300 @@ +package rpc + +import ( + "github.com/NethermindEth/juno/core/felt" +) + +type CasmCompiledContractClass struct { + EntryPointsByType CasmEntryPointsByType `json:"entry_points_by_type"` + ByteCode []*felt.Felt `json:"bytecode"` + Prime []*felt.Felt `json:"prime"` + CompilerVersion string `json:"compiler_version"` + Hints Hints `json:"hints"` + // a list of sizes of segments in the bytecode, each segment is hashed invidually when computing the bytecode hash + BytecodeSegmentLengths []int `json:"bytecode_segment_lengths,omitempty"` +} + +type CasmEntryPointsByType struct { + Constructor []CasmEntryPoint `json:"CONSTRUCTOR"` + External []CasmEntryPoint `json:"EXTERNAL"` + L1Handler []CasmEntryPoint `json:"L1_HANDLER"` +} + +type CasmEntryPoint struct { + DeprecatedCairoEntryPoint + // the hash of the right child + Builtin []string `json:"builtins"` +} + +// 2-tuple of pc value and an array of hints to execute, but adapted to a golang struct +type Hints struct { + Int int + HintArr []Hint +} + +func (hints *Hints) GetValues() (int, []Hint) { + return hints.Int, hints.HintArr +} + +type Hint any // TODO: finish the description and create an unmarshall func to every 'any' type + +type DeprecatedHint any // is one of these types: DeprecatedHintEnum, AssertAllAccessesUsed, AssertLtAssertValidInput, Felt252DictRead, or Felt252DictWrite + +type CoreHint any + +type StarknetHint any + +type DeprecatedHintEnum string + +const ( + AssertCurrentAccessIndicesIsEmpty DeprecatedHintEnum = "AssertCurrentAccessIndicesIsEmpty" + AssertAllKeysUsed DeprecatedHintEnum = "AssertAllKeysUsed" + AssertLeAssertThirdArcExcluded DeprecatedHintEnum = "AssertLeAssertThirdArcExcluded" +) + +type AssertAllAccessesUsed struct { + NotUsedAccesses CellRef `json:"n_used_accesses"` +} + +type CellRef struct { + Register Register `json:"Register"` + Offset int `json:"offset"` +} + +type Register string + +const ( + AP Register = "AP" + FP Register = "FP" +) + +type AssertLtAssertValidInput struct { + A ResOperand `json:"a"` + B ResOperand `json:"b"` +} + +type felt252Dict struct { + DictPtr ResOperand `json:"dict_ptr"` + Key ResOperand `json:"key"` +} + +type Felt252DictRead struct { + felt252Dict + ValueDst CellRef `json:"value_dst"` +} + +type Felt252DictWrite struct { + felt252Dict + Value ResOperand `json:"value"` +} + +type Felt252DictEntryInit felt252Dict + +type Felt252DictEntryUpdate struct { + DictPtr ResOperand `json:"dict_ptr"` + Value ResOperand `json:"value"` +} + +type ResOperand any // is one of these types: Deref, DoubleDeref, Immediate, or BinOp + +type Deref CellRef + +// A (CellRef, offsest) tuple, but adapted to a golang struct +type DoubleDeref struct { + CellRef CellRef + Offset int +} + +func (dd *DoubleDeref) GetValues() (CellRef, int) { + return dd.CellRef, dd.Offset +} + +type Immediate NumAsHex + +type Operation string + +const ( + Add Operation = "Add" + Mul Operation = "Mul" +) + +type BinOp struct { + Operation Operation `json:"op"` + A CellRef `json:"a"` + B any `json:"b"` // is one of these types: Deref or Immediate +} + +type AllocSegment struct { + Dst CellRef `json:"dst"` +} + +type baseLhsRhs struct { + Lhs ResOperand `json:"lhs"` + Rhs ResOperand `json:"rhs"` +} + +type TestLessThan struct { + baseLhsRhs + Dst CellRef `json:"dst"` +} + +type TestLessThanOrEqual TestLessThan + +type TestLessThanOrEqualAddress TestLessThan + +type WideMul128 struct { + baseLhsRhs + High CellRef `json:"high"` + Low CellRef `json:"low"` +} + +type DivMod struct { + baseLhsRhs + Quotient CellRef `json:"quotient"` + Remainder CellRef `json:"remainder"` +} + +type Uint256DivMod struct { + Dividend0 ResOperand `json:"dividend0"` + Dividend1 ResOperand `json:"dividend1"` + Divisor0 ResOperand `json:"divisor0"` + Divisor1 ResOperand `json:"divisor1"` + Quotient0 CellRef `json:"quotient0"` + Quotient1 CellRef `json:"quotient1"` + Remainder0 CellRef `json:"remainder0"` + Remainder1 CellRef `json:"remainder1"` +} + +type Uint512DivModByUint256 struct { + Uint256DivMod + Dividend2 ResOperand `json:"dividend2"` + Dividend3 ResOperand `json:"dividend3"` + Quotient2 CellRef `json:"quotient2"` + Quotient3 CellRef `json:"quotient3"` +} + +type SquareRoot struct { + Value ResOperand `json:"value"` + Dst CellRef `json:"dst"` +} + +type Uint256SquareRoot struct { + ValueLow ResOperand `json:"value_low"` + ValueHigh ResOperand `json:"value_high"` + Sqrt0 CellRef `json:"sqrt0"` + Sqrt1 CellRef `json:"sqrt1"` + RemainderLow CellRef `json:"remainder_low"` + RemainderHigh CellRef `json:"remainder_high"` + SqrtMul2MinusRemainderGeU128 CellRef `json:"sqrt_mul_2_minus_remainder_ge_u128"` +} + +type LinearSplit struct { + Value ResOperand `json:"value"` + Scalar ResOperand `json:"scalar"` + MaxX ResOperand `json:"max_x"` + X CellRef `json:"x"` + Y CellRef `json:"y"` +} + +type AllocFelt252Dict struct { + SegmentArenaPtr ResOperand `json:"segment_arena_ptr"` +} + +type GetSegmentArenaIndex struct { + DictEndPtr ResOperand `json:"dict_end_ptr"` + DictIndex CellRef `json:"dict_index"` +} + +type InitSquashDatas struct { + DictAccess ResOperand `json:"dict_access"` + PtrDiff ResOperand `json:"ptr_diff"` + NAccesses ResOperand `json:"n_accesses"` + BigKeys CellRef `json:"big_keys"` + FirstKeys CellRef `json:"first_key"` +} + +type GetCurrentAccessIndex struct { + RangeCheckPtr ResOperand `json:"range_check_ptr"` +} + +type GetCurrentAccessDelta struct { + IndexDeltaMinus1 CellRef `json:"index_delta_minus1"` +} + +type GetNextDictKey struct { + NextKey CellRef `json:"next_key"` +} + +type ShouldSkipSquashLoop struct { + ShouldSkipLoop CellRef `json:"should_skip_loop"` +} + +type ShouldContinueSquashLoop struct { + ShouldContinue CellRef `json:"should_continue"` +} + +type AssertLeFindSmallArcs struct { + RangeCheckPtr ResOperand `json:"range_check_ptr"` + A ResOperand `json:"a"` + B ResOperand `json:"b"` +} + +type AssertLeIsFirstArcExcluded struct { + SkipExcludeAFlag CellRef `json:"skip_exclude_a_flag"` +} + +type AssertLeIsSecondArcExcluded struct { + SkipExcludeBMinusA CellRef `json:"skip_exclude_b_minus_a"` +} + +type RandomEcPoint struct { + X CellRef `json:"x"` + Y CellRef `json:"y"` +} + +type FieldSqrt struct { + Val ResOperand `json:"val"` + Sqrt CellRef `json:"sqrt"` +} + +type DebugPrint struct { + Start ResOperand `json:"start"` + End ResOperand `json:"end"` +} + +type AllocConstantSize struct { + Size ResOperand `json:"size"` + Dst CellRef `json:"dst"` +} + +type U256InvModN struct { + B0 ResOperand `json:"b0"` + B1 ResOperand `json:"b1"` + N0 ResOperand `json:"n0"` + N1 ResOperand `json:"n1"` + G0OrNoInv CellRef `json:"g0_or_no_inv"` + G1Option CellRef `json:"g1_option"` + SOrR0 CellRef `json:"s_or_r0"` + SOrR1 CellRef `json:"s_or_r1"` + TOrR0 CellRef `json:"t_or_k0"` + TOrR1 CellRef `json:"t_or_k1"` +} + +type EvalCircuit struct { + NAddMods ResOperand `json:"n_add_mods"` + AddModBuiltin ResOperand `json:"add_mod_builtin"` + NMulMods ResOperand `json:"n_mul_mods"` + MulModBuiltin ResOperand `json:"mul_mod_builtin"` +} + +type SystemCall struct { + System ResOperand `json:"system"` +} + +type Cheatcode struct { + Selector NumAsHex `json:"selector"` + InputStart ResOperand `json:"input_start"` + InputEnd ResOperand `json:"input_end"` + OutputStart CellRef `json:"output_start"` + OutputEnd CellRef `json:"output_end"` +} diff --git a/utils/data.go b/utils/data.go index ce5d2098..4eae69e5 100644 --- a/utils/data.go +++ b/utils/data.go @@ -1,6 +1,9 @@ package utils -import "encoding/json" +import ( + "encoding/json" + "fmt" +) func UnwrapJSON(data map[string]interface{}, tag string) (map[string]interface{}, error) { if data[tag] != nil { @@ -16,3 +19,18 @@ func UnwrapJSON(data map[string]interface{}, tag string) (map[string]interface{} } return data, nil } + +func GetTypedFieldFromJSON[T any](data map[string]interface{}, tag string) (T, error) { + var resp T + rawResp, ok := data[tag] + if !ok { + return resp, fmt.Errorf("missing '%s' field in json object", tag) + } + + resp, ok = rawResp.(T) + if !ok { + return resp, fmt.Errorf("expected type '%T', got '%T'", resp, rawResp) + } + + return resp, nil +} From e21a8f7dfc65fbe806f6f30198cc0e65148a504b Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Wed, 30 Oct 2024 01:41:18 -0300 Subject: [PATCH 2/6] Creates unmarshal method for hint types --- rpc/types_executables.go | 155 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 149 insertions(+), 6 deletions(-) diff --git a/rpc/types_executables.go b/rpc/types_executables.go index eea0248d..1c0c5c11 100644 --- a/rpc/types_executables.go +++ b/rpc/types_executables.go @@ -1,6 +1,9 @@ package rpc import ( + "encoding/json" + "fmt" + "github.com/NethermindEth/juno/core/felt" ) @@ -38,11 +41,151 @@ func (hints *Hints) GetValues() (int, []Hint) { type Hint any // TODO: finish the description and create an unmarshall func to every 'any' type -type DeprecatedHint any // is one of these types: DeprecatedHintEnum, AssertAllAccessesUsed, AssertLtAssertValidInput, Felt252DictRead, or Felt252DictWrite - -type CoreHint any - -type StarknetHint any +type DeprecatedHint struct { + any // is one of these types: DeprecatedHintEnum, AssertAllAccessesUsed, AssertLtAssertValidInput, Felt252DictRead, or Felt252DictWrite +} + +// UnmarshalJSON unmarshals the JSON data into a DeprecatedHint object. +// +// Parameters: +// - data: The JSON data to be unmarshalled +// Returns: +// - error: An error if the unmarshalling process fails +func (depHint *DeprecatedHint) UnmarshalJSON(data []byte) error { + var dec interface{} + if err := json.Unmarshal(data, &dec); err != nil { + return err + } + + switch hint := dec.(type) { + case string: + *depHint = DeprecatedHint{DeprecatedHintEnum(hint)} + case AssertAllAccessesUsed: + *depHint = DeprecatedHint{hint} + case AssertLtAssertValidInput: + *depHint = DeprecatedHint{hint} + case Felt252DictRead: + *depHint = DeprecatedHint{hint} + case Felt252DictWrite: + *depHint = DeprecatedHint{hint} + default: + return fmt.Errorf("failed to unmarshal 'DeprecatedHint'") + } + + return nil +} + +type CoreHint struct { + any // it can be a wide variety of types. Ref: https://github.com/starkware-libs/starknet-specs/blob/19ab9d4df4ae3acc1a52cde5a43a7cace08bcc4b/api/starknet_executables.json#L403 +} + +// UnmarshalJSON unmarshals the JSON data into a CoreHint object. +// +// Parameters: +// - data: The JSON data to be unmarshalled +// Returns: +// - error: An error if the unmarshalling process fails +func (coreHint *CoreHint) UnmarshalJSON(data []byte) error { + var dec interface{} + if err := json.Unmarshal(data, &dec); err != nil { + return err + } + + switch hint := dec.(type) { + case AllocSegment: + *coreHint = CoreHint{hint} + case TestLessThan: + *coreHint = CoreHint{hint} + case TestLessThanOrEqual: + *coreHint = CoreHint{hint} + case TestLessThanOrEqualAddress: + *coreHint = CoreHint{hint} + case WideMul128: + *coreHint = CoreHint{hint} + case DivMod: + *coreHint = CoreHint{hint} + case Uint256DivMod: + *coreHint = CoreHint{hint} + case Uint512DivModByUint256: + *coreHint = CoreHint{hint} + case SquareRoot: + *coreHint = CoreHint{hint} + case Uint256SquareRoot: + *coreHint = CoreHint{hint} + case LinearSplit: + *coreHint = CoreHint{hint} + case AllocFelt252Dict: + *coreHint = CoreHint{hint} + case Felt252DictEntryInit: + *coreHint = CoreHint{hint} + case Felt252DictEntryUpdate: + *coreHint = CoreHint{hint} + case GetSegmentArenaIndex: + *coreHint = CoreHint{hint} + case InitSquashData: + *coreHint = CoreHint{hint} + case GetCurrentAccessIndex: + *coreHint = CoreHint{hint} + case ShouldSkipSquashLoop: + *coreHint = CoreHint{hint} + case GetCurrentAccessDelta: + *coreHint = CoreHint{hint} + case ShouldContinueSquashLoop: + *coreHint = CoreHint{hint} + case GetNextDictKey: + *coreHint = CoreHint{hint} + case AssertLeFindSmallArcs: + *coreHint = CoreHint{hint} + case AssertLeIsFirstArcExcluded: + *coreHint = CoreHint{hint} + case AssertLeIsSecondArcExcluded: + *coreHint = CoreHint{hint} + case RandomEcPoint: + *coreHint = CoreHint{hint} + case FieldSqrt: + *coreHint = CoreHint{hint} + case DebugPrint: + *coreHint = CoreHint{hint} + case AllocConstantSize: + *coreHint = CoreHint{hint} + case U256InvModN: + *coreHint = CoreHint{hint} + case EvalCircuit: + *coreHint = CoreHint{hint} + default: + return fmt.Errorf("failed to unmarshal 'CoreHint'") + } + + return nil +} + +type StarknetHint struct { + any // is one of these types: SystemCall or Cheatcode +} + +// UnmarshalJSON unmarshals the JSON data into a StarknetHint object. +// +// Parameters: +// - data: The JSON data to be unmarshalled +// Returns: +// - error: An error if the unmarshalling process fails +func (strkHint *StarknetHint) UnmarshalJSON(data []byte) error { + var dec interface{} + if err := json.Unmarshal(data, &dec); err != nil { + return err + } + + switch hint := dec.(type) { + case SystemCall: + *strkHint = StarknetHint{hint} + case Cheatcode: + *strkHint = StarknetHint{hint} + default: + return fmt.Errorf("failed to unmarshal 'StarknetHint'") + } + + return nil +} type DeprecatedHintEnum string @@ -205,7 +348,7 @@ type GetSegmentArenaIndex struct { DictIndex CellRef `json:"dict_index"` } -type InitSquashDatas struct { +type InitSquashData struct { DictAccess ResOperand `json:"dict_access"` PtrDiff ResOperand `json:"ptr_diff"` NAccesses ResOperand `json:"n_accesses"` From 5d35cd76d835a1a44c9c3b928d67cb884978a990 Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Wed, 30 Oct 2024 12:20:01 -0300 Subject: [PATCH 3/6] Finishes CompiledCasm method --- mocks/mock_rpc_provider.go | 15 +++ rpc/errors.go | 4 + rpc/executables.go | 10 +- rpc/provider.go | 1 + rpc/types_executables.go | 211 ++++++++++++------------------------- 5 files changed, 90 insertions(+), 151 deletions(-) diff --git a/mocks/mock_rpc_provider.go b/mocks/mock_rpc_provider.go index 9a62fc94..cbaa68f6 100644 --- a/mocks/mock_rpc_provider.go +++ b/mocks/mock_rpc_provider.go @@ -251,6 +251,21 @@ func (mr *MockRpcProviderMockRecorder) ClassHashAt(ctx, blockID, contractAddress return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClassHashAt", reflect.TypeOf((*MockRpcProvider)(nil).ClassHashAt), ctx, blockID, contractAddress) } +// CompiledCasm mocks base method. +func (m *MockRpcProvider) CompiledCasm(ctx context.Context, classHash *felt.Felt) (*rpc.CasmCompiledContractClass, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CompiledCasm", ctx, classHash) + ret0, _ := ret[0].(*rpc.CasmCompiledContractClass) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CompiledCasm indicates an expected call of CompiledCasm. +func (mr *MockRpcProviderMockRecorder) CompiledCasm(ctx, classHash any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CompiledCasm", reflect.TypeOf((*MockRpcProvider)(nil).CompiledCasm), ctx, classHash) +} + // EstimateFee mocks base method. func (m *MockRpcProvider) EstimateFee(ctx context.Context, requests []rpc.BroadcastTxn, simulationFlags []rpc.SimulationFlag, blockID rpc.BlockID) ([]rpc.FeeEstimation, error) { m.ctrl.T.Helper() diff --git a/rpc/errors.go b/rpc/errors.go index d0effbf6..d8d1cb49 100644 --- a/rpc/errors.go +++ b/rpc/errors.go @@ -198,4 +198,8 @@ var ( Code: 63, Message: "An unexpected error occurred", } + ErrCompilationError = &RPCError{ + Code: 9999, //placeholder number as this error has no code so far. TODO: change this with the next updates + Message: "More data about the compilation failure", + } ) diff --git a/rpc/executables.go b/rpc/executables.go index 5e6cd7b9..48fcc686 100644 --- a/rpc/executables.go +++ b/rpc/executables.go @@ -12,13 +12,13 @@ import ( // - ctx: The context.Context used for the request // - classHash: The hash of the contract class whose CASM will be returned // Returns: -// - *felt.Felt: The compiled contract class +// - CasmCompiledContractClass: The compiled contract class // - error: An error if any occurred during the execution -func (provider *Provider) CompiledCasm(ctx context.Context, classHash *felt.Felt) (*felt.Felt, error) { - var result *felt.Felt +func (provider *Provider) CompiledCasm(ctx context.Context, classHash *felt.Felt) (*CasmCompiledContractClass, error) { + var result CasmCompiledContractClass if err := do(ctx, provider.c, "starknet_getCompiledCasm", &result, classHash); err != nil { - return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) + return nil, tryUnwrapToRPCErr(err, ErrClassHashNotFound, ErrCompilationError) } - return result, nil + return &result, nil } diff --git a/rpc/provider.go b/rpc/provider.go index 36852c5a..f29ab549 100644 --- a/rpc/provider.go +++ b/rpc/provider.go @@ -56,6 +56,7 @@ type RpcProvider interface { Class(ctx context.Context, blockID BlockID, classHash *felt.Felt) (ClassOutput, error) ClassAt(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (ClassOutput, error) ClassHashAt(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (*felt.Felt, error) + CompiledCasm(ctx context.Context, classHash *felt.Felt) (*CasmCompiledContractClass, error) EstimateFee(ctx context.Context, requests []BroadcastTxn, simulationFlags []SimulationFlag, blockID BlockID) ([]FeeEstimation, error) EstimateMessageFee(ctx context.Context, msg MsgFromL1, blockID BlockID) (*FeeEstimation, error) Events(ctx context.Context, input EventsInput) (*EventChunk, error) diff --git a/rpc/types_executables.go b/rpc/types_executables.go index 1c0c5c11..616c2867 100644 --- a/rpc/types_executables.go +++ b/rpc/types_executables.go @@ -1,9 +1,6 @@ package rpc import ( - "encoding/json" - "fmt" - "github.com/NethermindEth/juno/core/felt" ) @@ -35,156 +32,64 @@ type Hints struct { HintArr []Hint } -func (hints *Hints) GetValues() (int, []Hint) { +func (hints *Hints) Values() (int, []Hint) { return hints.Int, hints.HintArr } -type Hint any // TODO: finish the description and create an unmarshall func to every 'any' type +func (hints *Hints) Tuple() [2]any { + return [2]any{hints.Int, hints.HintArr} +} + +type Hint struct { + DeprecatedHint + CoreHint + StarknetHint +} type DeprecatedHint struct { - any // is one of these types: DeprecatedHintEnum, AssertAllAccessesUsed, AssertLtAssertValidInput, Felt252DictRead, or Felt252DictWrite -} - -// UnmarshalJSON unmarshals the JSON data into a DeprecatedHint object. -// -// Parameters: -// - data: The JSON data to be unmarshalled -// Returns: -// - error: An error if the unmarshalling process fails -func (depHint *DeprecatedHint) UnmarshalJSON(data []byte) error { - var dec interface{} - if err := json.Unmarshal(data, &dec); err != nil { - return err - } - - switch hint := dec.(type) { - case string: - *depHint = DeprecatedHint{DeprecatedHintEnum(hint)} - case AssertAllAccessesUsed: - *depHint = DeprecatedHint{hint} - case AssertLtAssertValidInput: - *depHint = DeprecatedHint{hint} - case Felt252DictRead: - *depHint = DeprecatedHint{hint} - case Felt252DictWrite: - *depHint = DeprecatedHint{hint} - default: - return fmt.Errorf("failed to unmarshal 'DeprecatedHint'") - } - - return nil + DeprecatedHintEnum + AssertAllAccessesUsed AssertAllAccessesUsed `json:",omitempty"` + AssertLtAssertValidInput AssertLtAssertValidInput `json:",omitempty"` + Felt252DictRead Felt252DictRead `json:",omitempty"` + Felt252DictWrite Felt252DictWrite `json:",omitempty"` } type CoreHint struct { - any // it can be a wide variety of types. Ref: https://github.com/starkware-libs/starknet-specs/blob/19ab9d4df4ae3acc1a52cde5a43a7cace08bcc4b/api/starknet_executables.json#L403 -} - -// UnmarshalJSON unmarshals the JSON data into a CoreHint object. -// -// Parameters: -// - data: The JSON data to be unmarshalled -// Returns: -// - error: An error if the unmarshalling process fails -func (coreHint *CoreHint) UnmarshalJSON(data []byte) error { - var dec interface{} - if err := json.Unmarshal(data, &dec); err != nil { - return err - } - - switch hint := dec.(type) { - case AllocSegment: - *coreHint = CoreHint{hint} - case TestLessThan: - *coreHint = CoreHint{hint} - case TestLessThanOrEqual: - *coreHint = CoreHint{hint} - case TestLessThanOrEqualAddress: - *coreHint = CoreHint{hint} - case WideMul128: - *coreHint = CoreHint{hint} - case DivMod: - *coreHint = CoreHint{hint} - case Uint256DivMod: - *coreHint = CoreHint{hint} - case Uint512DivModByUint256: - *coreHint = CoreHint{hint} - case SquareRoot: - *coreHint = CoreHint{hint} - case Uint256SquareRoot: - *coreHint = CoreHint{hint} - case LinearSplit: - *coreHint = CoreHint{hint} - case AllocFelt252Dict: - *coreHint = CoreHint{hint} - case Felt252DictEntryInit: - *coreHint = CoreHint{hint} - case Felt252DictEntryUpdate: - *coreHint = CoreHint{hint} - case GetSegmentArenaIndex: - *coreHint = CoreHint{hint} - case InitSquashData: - *coreHint = CoreHint{hint} - case GetCurrentAccessIndex: - *coreHint = CoreHint{hint} - case ShouldSkipSquashLoop: - *coreHint = CoreHint{hint} - case GetCurrentAccessDelta: - *coreHint = CoreHint{hint} - case ShouldContinueSquashLoop: - *coreHint = CoreHint{hint} - case GetNextDictKey: - *coreHint = CoreHint{hint} - case AssertLeFindSmallArcs: - *coreHint = CoreHint{hint} - case AssertLeIsFirstArcExcluded: - *coreHint = CoreHint{hint} - case AssertLeIsSecondArcExcluded: - *coreHint = CoreHint{hint} - case RandomEcPoint: - *coreHint = CoreHint{hint} - case FieldSqrt: - *coreHint = CoreHint{hint} - case DebugPrint: - *coreHint = CoreHint{hint} - case AllocConstantSize: - *coreHint = CoreHint{hint} - case U256InvModN: - *coreHint = CoreHint{hint} - case EvalCircuit: - *coreHint = CoreHint{hint} - default: - return fmt.Errorf("failed to unmarshal 'CoreHint'") - } - - return nil + AllocConstantSize AllocConstantSize `json:",omitempty"` + AllocFelt252Dict AllocFelt252Dict `json:",omitempty"` + AllocSegment AllocSegment `json:",omitempty"` + AssertLeFindSmallArcs AssertLeFindSmallArcs `json:",omitempty"` + AssertLeIsFirstArcExcluded AssertLeIsFirstArcExcluded `json:",omitempty"` + AssertLeIsSecondArcExcluded AssertLeIsSecondArcExcluded `json:",omitempty"` + DebugPrint DebugPrint `json:",omitempty"` + DivMod DivMod `json:",omitempty"` + EvalCircuit EvalCircuit `json:",omitempty"` + Felt252DictEntryInit Felt252DictEntryInit `json:",omitempty"` + Felt252DictEntryUpdate Felt252DictEntryUpdate `json:",omitempty"` + FieldSqrt FieldSqrt `json:",omitempty"` + GetCurrentAccessDelta GetCurrentAccessDelta `json:",omitempty"` + GetCurrentAccessIndex GetCurrentAccessIndex `json:",omitempty"` + GetNextDictKey GetNextDictKey `json:",omitempty"` + GetSegmentArenaIndex GetSegmentArenaIndex `json:",omitempty"` + InitSquashData InitSquashData `json:",omitempty"` + LinearSplit LinearSplit `json:",omitempty"` + RandomEcPoint RandomEcPoint `json:",omitempty"` + ShouldContinueSquashLoop ShouldContinueSquashLoop `json:",omitempty"` + ShouldSkipSquashLoop ShouldSkipSquashLoop `json:",omitempty"` + SquareRoot SquareRoot `json:",omitempty"` + TestLessThan TestLessThan `json:",omitempty"` + TestLessThanOrEqual TestLessThanOrEqual `json:",omitempty"` + TestLessThanOrEqualAddress TestLessThanOrEqualAddress `json:",omitempty"` + U256InvModN U256InvModN `json:",omitempty"` + Uint256DivMod Uint256DivMod `json:",omitempty"` + Uint256SquareRoot Uint256SquareRoot `json:",omitempty"` + Uint512DivModByUint256 Uint512DivModByUint256 `json:",omitempty"` + WideMul128 WideMul128 `json:",omitempty"` } type StarknetHint struct { - any // is one of these types: SystemCall or Cheatcode -} - -// UnmarshalJSON unmarshals the JSON data into a StarknetHint object. -// -// Parameters: -// - data: The JSON data to be unmarshalled -// Returns: -// - error: An error if the unmarshalling process fails -func (strkHint *StarknetHint) UnmarshalJSON(data []byte) error { - var dec interface{} - if err := json.Unmarshal(data, &dec); err != nil { - return err - } - - switch hint := dec.(type) { - case SystemCall: - *strkHint = StarknetHint{hint} - case Cheatcode: - *strkHint = StarknetHint{hint} - default: - return fmt.Errorf("failed to unmarshal 'StarknetHint'") - } - - return nil + Cheatcode Cheatcode `json:",omitempty"` + SystemCall SystemCall `json:",omitempty"` } type DeprecatedHintEnum string @@ -200,7 +105,7 @@ type AssertAllAccessesUsed struct { } type CellRef struct { - Register Register `json:"Register"` + Register Register `json:"register"` Offset int `json:"offset"` } @@ -238,7 +143,12 @@ type Felt252DictEntryUpdate struct { Value ResOperand `json:"value"` } -type ResOperand any // is one of these types: Deref, DoubleDeref, Immediate, or BinOp +type ResOperand struct { + BinOp BinOp `json:",omitempty"` + Deref Deref `json:",omitempty"` + DoubleDeref DoubleDeref `json:",omitempty"` + Immediate Immediate `json:",omitempty"` +} type Deref CellRef @@ -248,10 +158,14 @@ type DoubleDeref struct { Offset int } -func (dd *DoubleDeref) GetValues() (CellRef, int) { +func (dd *DoubleDeref) Values() (CellRef, int) { return dd.CellRef, dd.Offset } +func (dd *DoubleDeref) Tuple() [2]any { + return [2]any{dd.CellRef, dd.Offset} +} + type Immediate NumAsHex type Operation string @@ -264,7 +178,12 @@ const ( type BinOp struct { Operation Operation `json:"op"` A CellRef `json:"a"` - B any `json:"b"` // is one of these types: Deref or Immediate + B B `json:"b"` +} + +type B struct { + Deref Deref `json:",omitempty"` + Immediate Immediate `json:",omitempty"` } type AllocSegment struct { From 4ddb45cf1ce5c942ad87f0da7905e197b813bd6c Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Wed, 30 Oct 2024 12:22:14 -0300 Subject: [PATCH 4/6] Creates test placeholder --- rpc/executables_test.go | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rpc/executables_test.go diff --git a/rpc/executables_test.go b/rpc/executables_test.go new file mode 100644 index 00000000..f09e44fc --- /dev/null +++ b/rpc/executables_test.go @@ -0,0 +1,7 @@ +package rpc + +import "testing" + +func TestCompiledCasm(t *testing.T) { + t.Skip("TODO: create a test before merge") +} From a21c78861cfd134d66e71f2f7b3ffbdc2c58ba1f Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Fri, 1 Nov 2024 01:17:04 -0300 Subject: [PATCH 5/6] Fixes PR comments notes --- rpc/types_executables.go | 2 +- utils/data.go | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/rpc/types_executables.go b/rpc/types_executables.go index 616c2867..f45afad9 100644 --- a/rpc/types_executables.go +++ b/rpc/types_executables.go @@ -7,7 +7,7 @@ import ( type CasmCompiledContractClass struct { EntryPointsByType CasmEntryPointsByType `json:"entry_points_by_type"` ByteCode []*felt.Felt `json:"bytecode"` - Prime []*felt.Felt `json:"prime"` + Prime NumAsHex `json:"prime"` CompilerVersion string `json:"compiler_version"` Hints Hints `json:"hints"` // a list of sizes of segments in the bytecode, each segment is hashed invidually when computing the bytecode hash diff --git a/utils/data.go b/utils/data.go index 4eae69e5..2f94bcef 100644 --- a/utils/data.go +++ b/utils/data.go @@ -2,7 +2,6 @@ package utils import ( "encoding/json" - "fmt" ) func UnwrapJSON(data map[string]interface{}, tag string) (map[string]interface{}, error) { @@ -19,18 +18,3 @@ func UnwrapJSON(data map[string]interface{}, tag string) (map[string]interface{} } return data, nil } - -func GetTypedFieldFromJSON[T any](data map[string]interface{}, tag string) (T, error) { - var resp T - rawResp, ok := data[tag] - if !ok { - return resp, fmt.Errorf("missing '%s' field in json object", tag) - } - - resp, ok = rawResp.(T) - if !ok { - return resp, fmt.Errorf("expected type '%T', got '%T'", resp, rawResp) - } - - return resp, nil -} From 543825189f452429af8cdd0dcc75b04556466042 Mon Sep 17 00:00:00 2001 From: thiagodeev Date: Wed, 6 Nov 2024 11:05:32 -0300 Subject: [PATCH 6/6] Fix Hints type --- rpc/types_executables.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/types_executables.go b/rpc/types_executables.go index f45afad9..b320e4f9 100644 --- a/rpc/types_executables.go +++ b/rpc/types_executables.go @@ -9,7 +9,7 @@ type CasmCompiledContractClass struct { ByteCode []*felt.Felt `json:"bytecode"` Prime NumAsHex `json:"prime"` CompilerVersion string `json:"compiler_version"` - Hints Hints `json:"hints"` + Hints []Hints `json:"hints"` // a list of sizes of segments in the bytecode, each segment is hashed invidually when computing the bytecode hash BytecodeSegmentLengths []int `json:"bytecode_segment_lengths,omitempty"` }