From 5b415f3c6b540468586ddfcd0494ba1b15caaeea Mon Sep 17 00:00:00 2001 From: DarkLord017 Date: Sun, 15 Sep 2024 15:28:53 +0530 Subject: [PATCH 1/4] Added makefile for testing framework --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..bbaa4959 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# Makefile + +# Target to run all the tests +unit: + @echo "Running unit tests" + + go test ./athena_abi + +# Target to clean up the project +clean: + @echo "Cleaning up" + go clean From 29c805deed2c4409b8f9e127b611caebda103bfa Mon Sep 17 00:00:00 2001 From: DarkLord017 Date: Sun, 15 Sep 2024 22:02:59 +0530 Subject: [PATCH 2/4] Added core.go --- athena_abi/core.go | 169 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 athena_abi/core.go diff --git a/athena_abi/core.go b/athena_abi/core.go new file mode 100644 index 00000000..621c7b1e --- /dev/null +++ b/athena_abi/core.go @@ -0,0 +1,169 @@ +package athena_abi + +import ( + "errors" + "log" +) + +type b256 [32]byte + +type StarknetABI struct { + ABIName *string + ClassHash b256 + Functions map[string]AbiFunction + Events map[string]AbiEvent + Constructor []AbiParameter + L1Handler *AbiFunction + ImplementedInterfaces map[string]AbiInterface +} + +// Parse Starknet ABI from JSON +// @param abiJSON +// @param abiname +// @param classHash +func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, classHash b256) (*StarknetABI, error) { + if abiJson == nil { + return nil, errors.New("unable to parse ABI") + } + groupedAbi := GroupAbiByType(abiJson) + + // Parse defined types (structs and enums) + if groupedAbi["type_def"] == nil { + log.Println("No type definitions found in ABI") + } + definedTypes, err := ParseEnumsAndStructs(groupedAbi["type_def"]) + if err != nil { + sortedDefs, errDef := TopoSortTypeDefs(groupedAbi["type_def"]) + if errDef != nil { + return nil, errors.New("unable to parse types") + } + defineTypes, errDtypes := ParseEnumsAndStructs(sortedDefs) + definedTypes = defineTypes + if errDtypes != nil { + return nil, errors.New("unable to parse types") + } + log.Println("ABI Struct and Enum definitions out of order & required topological sorting") + } + + // Parse interfaces + var definedInterfaces []AbiInterface + if groupedAbi["interface"] == nil { + log.Println("No interfaces found in ABI") + } + for _, iface := range groupedAbi["interface"] { + functions := []AbiFunction{} + for _, funcData := range iface["items"].([]interface{}) { + parsedAbi, errWhileParsing := ParseAbiFunction(funcData.(map[string]interface{}), definedTypes) + if errWhileParsing != nil { + return nil, errors.New("unable to parse interfaces") + } + functions = append(functions, *parsedAbi) + } + definedInterfaces = append(definedInterfaces, AbiInterface{ + name: iface["name"].(string), + functions: functions, + }) + } + + // Parse functions + if groupedAbi["function"] == nil { + log.Println("No functions found in ABI") + } + functions := make(map[string]AbiFunction) + for _, functionData := range groupedAbi["function"] { + funcName := functionData["name"].(string) + abiFunc, errParsingFunctions := ParseAbiFunction(functionData, definedTypes) + if errParsingFunctions != nil { + return nil, errors.New("unable to parse functions") + } + functions[funcName] = *abiFunc + } + + // Add functions from interfaces + + for _, iface := range definedInterfaces { + for _, function := range iface.functions { + functions[function.name] = function + } + } + + // Parse events + parsedAbiEvents := []AbiEvent{} + if groupedAbi["event"] == nil { + log.Println("No events found in ABI") + } + for _, eventData := range groupedAbi["event"] { + parsedEvent, errParsingEvent := ParseAbiEvent(eventData, definedTypes) + if errParsingEvent != nil { + return nil, errors.New("unable to parse events") + } + parsedAbiEvents = append(parsedAbiEvents, *parsedEvent) + } + if len(parsedAbiEvents) == 0 { + log.Println("No events found in ABI") + } + events := make(map[string]AbiEvent) + for _, event := range parsedAbiEvents { + if event.name != "" { + events[event.name] = event + } + } + + // Parse constructor + var constructor []AbiParameter + if len(groupedAbi["constructor"]) == 1 { + for _, paramData := range groupedAbi["constructor"][0]["inputs"].([]interface{}) { + param := paramData.(map[string]interface{}) + typed, errorParsingType := parseType(param["type"].(string), definedTypes) + if errorParsingType != nil { + return nil, errors.New("unable to parse constructor") + } + constructor = append(constructor, AbiParameter{ + Name: param["name"].(string), + Type: typed, + }) + } + } else { + constructor = nil + } + + // Parse L1 handler + var l1Handler *AbiFunction + if len(groupedAbi["l1_handler"]) == 1 { + handler, errorParsingFunction := ParseAbiFunction(groupedAbi["l1_handler"][0], definedTypes) + if errorParsingFunction != nil { + return nil, errors.New("unable to parse L1 handler") + } + l1Handler = handler + } else { + l1Handler = nil + } + + // Parse implemented interfaces + implementedInterfaces := make(map[string]AbiInterface) + implArray, ok := groupedAbi["impl"] + if !ok { + return nil, errors.New("unable to parse implemented interfaces") + } + for _, implData := range implArray { + implMap := implData + if ifaceName, ok := implMap["interface_name"].(string); ok { + for _, iface := range definedInterfaces { + if iface.name == ifaceName { + implementedInterfaces[iface.name] = iface + } + } + } + } + + // Return the populated StarknetAbi struct + return &StarknetABI{ + ABIName: &abiName, + ClassHash: classHash, + Functions: functions, + Events: events, + Constructor: constructor, + L1Handler: l1Handler, + ImplementedInterfaces: implementedInterfaces, + }, nil +} From ff259fac26a951ccd27d57be33dc45bb1288eb22 Mon Sep 17 00:00:00 2001 From: Shourya Goel Date: Sun, 15 Sep 2024 22:54:25 +0530 Subject: [PATCH 3/4] Delete Makefile --- Makefile | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 Makefile diff --git a/Makefile b/Makefile deleted file mode 100644 index bbaa4959..00000000 --- a/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# Makefile - -# Target to run all the tests -unit: - @echo "Running unit tests" - - go test ./athena_abi - -# Target to clean up the project -clean: - @echo "Cleaning up" - go clean From adac2a1dfe9ae5f2ede1db5b53760269feb7a796 Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:14:26 +0530 Subject: [PATCH 4/4] Improved code quality and removed unnecessary checks --- athena_abi/core.go | 61 ++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/athena_abi/core.go b/athena_abi/core.go index 621c7b1e..3151afca 100644 --- a/athena_abi/core.go +++ b/athena_abi/core.go @@ -5,11 +5,9 @@ import ( "log" ) -type b256 [32]byte - type StarknetABI struct { ABIName *string - ClassHash b256 + ClassHash []byte Functions map[string]AbiFunction Events map[string]AbiEvent Constructor []AbiParameter @@ -17,45 +15,47 @@ type StarknetABI struct { ImplementedInterfaces map[string]AbiInterface } +// Declare errors +var ( + errParseDefinedTypes = errors.New("unable to parse defined types") + errParseInterfaces = errors.New("unable to parse interfaces") + errParseFunctions = errors.New("unable to parse functions") + errParseEvents = errors.New("unable to parse events") + errParseConstructor = errors.New("unable to parse constructor") + errParseL1Handler = errors.New("unable to parse L1 handler") + errParseImplementedInterfaces = errors.New("unable to parse implemented interfaces") +) + // Parse Starknet ABI from JSON // @param abiJSON // @param abiname // @param classHash -func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, classHash b256) (*StarknetABI, error) { - if abiJson == nil { - return nil, errors.New("unable to parse ABI") - } +func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, classHash []byte) (*StarknetABI, error) { groupedAbi := GroupAbiByType(abiJson) // Parse defined types (structs and enums) - if groupedAbi["type_def"] == nil { - log.Println("No type definitions found in ABI") - } definedTypes, err := ParseEnumsAndStructs(groupedAbi["type_def"]) if err != nil { sortedDefs, errDef := TopoSortTypeDefs(groupedAbi["type_def"]) - if errDef != nil { - return nil, errors.New("unable to parse types") + if errDef == nil { + defineTypes, errDtypes := ParseEnumsAndStructs(sortedDefs) + definedTypes = defineTypes + errDef = errDtypes } - defineTypes, errDtypes := ParseEnumsAndStructs(sortedDefs) - definedTypes = defineTypes - if errDtypes != nil { - return nil, errors.New("unable to parse types") + if errDef != nil { + return nil, errParseDefinedTypes } log.Println("ABI Struct and Enum definitions out of order & required topological sorting") } // Parse interfaces var definedInterfaces []AbiInterface - if groupedAbi["interface"] == nil { - log.Println("No interfaces found in ABI") - } for _, iface := range groupedAbi["interface"] { functions := []AbiFunction{} for _, funcData := range iface["items"].([]interface{}) { parsedAbi, errWhileParsing := ParseAbiFunction(funcData.(map[string]interface{}), definedTypes) if errWhileParsing != nil { - return nil, errors.New("unable to parse interfaces") + return nil, errParseInterfaces } functions = append(functions, *parsedAbi) } @@ -66,21 +66,17 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class } // Parse functions - if groupedAbi["function"] == nil { - log.Println("No functions found in ABI") - } functions := make(map[string]AbiFunction) for _, functionData := range groupedAbi["function"] { funcName := functionData["name"].(string) abiFunc, errParsingFunctions := ParseAbiFunction(functionData, definedTypes) if errParsingFunctions != nil { - return nil, errors.New("unable to parse functions") + return nil, errParseFunctions } functions[funcName] = *abiFunc } // Add functions from interfaces - for _, iface := range definedInterfaces { for _, function := range iface.functions { functions[function.name] = function @@ -89,19 +85,14 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse events parsedAbiEvents := []AbiEvent{} - if groupedAbi["event"] == nil { - log.Println("No events found in ABI") - } for _, eventData := range groupedAbi["event"] { parsedEvent, errParsingEvent := ParseAbiEvent(eventData, definedTypes) if errParsingEvent != nil { - return nil, errors.New("unable to parse events") + return nil, errParseEvents } parsedAbiEvents = append(parsedAbiEvents, *parsedEvent) } - if len(parsedAbiEvents) == 0 { - log.Println("No events found in ABI") - } + events := make(map[string]AbiEvent) for _, event := range parsedAbiEvents { if event.name != "" { @@ -116,7 +107,7 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class param := paramData.(map[string]interface{}) typed, errorParsingType := parseType(param["type"].(string), definedTypes) if errorParsingType != nil { - return nil, errors.New("unable to parse constructor") + return nil, errParseConstructor } constructor = append(constructor, AbiParameter{ Name: param["name"].(string), @@ -132,7 +123,7 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class if len(groupedAbi["l1_handler"]) == 1 { handler, errorParsingFunction := ParseAbiFunction(groupedAbi["l1_handler"][0], definedTypes) if errorParsingFunction != nil { - return nil, errors.New("unable to parse L1 handler") + return nil, errParseL1Handler } l1Handler = handler } else { @@ -143,7 +134,7 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class implementedInterfaces := make(map[string]AbiInterface) implArray, ok := groupedAbi["impl"] if !ok { - return nil, errors.New("unable to parse implemented interfaces") + return nil, errParseImplementedInterfaces } for _, implData := range implArray { implMap := implData