From 4aaaa625e09235f1b47285e0fd0c5bc208b4bb4c Mon Sep 17 00:00:00 2001 From: rishikpulhani Date: Tue, 24 Sep 2024 16:11:42 +0530 Subject: [PATCH] finished with parse_full_abi_test.go and made changes to parse.go and core.go and cleaned the code --- athena_abi/core.go | 38 +--------- athena_abi/parse.go | 114 ++---------------------------- athena_abi/parse_full_abi_test.go | 64 ----------------- athena_abi/parse_struct_test.go | 1 - 4 files changed, 7 insertions(+), 210 deletions(-) diff --git a/athena_abi/core.go b/athena_abi/core.go index d2a125d9..93f98fcd 100644 --- a/athena_abi/core.go +++ b/athena_abi/core.go @@ -2,7 +2,6 @@ package athena_abi import ( "errors" - "fmt" "log" ) @@ -35,11 +34,7 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class groupedAbi := GroupAbiByType(abiJson) // Parse defined types (structs and enums) - fmt.Println("hello") - fmt.Println("grouped abi", groupedAbi["type_def"]) definedTypes, err := ParseEnumsAndStructs(groupedAbi["type_def"]) - fmt.Println("defined types Map contents:", definedTypes) - fmt.Println("is there error", err) if err != nil { sortedDefs, errDef := TopoSortTypeDefs(groupedAbi["type_def"]) if errDef == nil { @@ -55,7 +50,6 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse interfaces var definedInterfaces []AbiInterface - fmt.Println("now parsing interfaces") for _, iface := range groupedAbi["interface"] { functions := []AbiFunction{} for _, funcData := range iface["items"].([]interface{}) { @@ -73,7 +67,6 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse functions functions := make(map[string]AbiFunction) - fmt.Println("now parsing functions") for _, functionData := range groupedAbi["function"] { funcName := functionData["name"].(string) abiFunc, errParsingFunctions := ParseAbiFunction(functionData, definedTypes) @@ -92,29 +85,20 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse events parsedAbiEvents := []AbiEvent{} - fmt.Println("now parsing events") - fmt.Println("the grouped abi events is ", groupedAbi["event"]) for _, eventData := range groupedAbi["event"] { - fmt.Println("eventdata is ", eventData) parsedEvent, errParsingEvent := ParseAbiEvent(eventData, definedTypes) - fmt.Println("parsed event is ", parsedEvent) - fmt.Println("the err is ", errParsingEvent) if errParsingEvent != nil { return nil, errParseEvents } - //parsedAbiEvents = append(parsedAbiEvents, *parsedEvent) if parsedEvent != nil { parsedAbiEvents = append(parsedAbiEvents, *parsedEvent) } else { - // Handle the nil case if necessary - //return nil, errors.New("parsed event is nil") continue } } events := make(map[string]AbiEvent) - fmt.Println("parsedabievents are ", parsedAbiEvents) for _, event := range parsedAbiEvents { if event.name != "" { events[event.name] = event @@ -123,7 +107,6 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse constructor var constructor []AbiParameter - fmt.Println("now parsing constructor") if len(groupedAbi["constructor"]) == 1 { for _, paramData := range groupedAbi["constructor"][0]["inputs"].([]interface{}) { param := paramData.(map[string]interface{}) @@ -142,7 +125,6 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse L1 handler var l1Handler *AbiFunction - fmt.Println("now parsing l1handler") if len(groupedAbi["l1_handler"]) == 1 { handler, errorParsingFunction := ParseAbiFunction(groupedAbi["l1_handler"][0], definedTypes) if errorParsingFunction != nil { @@ -155,12 +137,7 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class // Parse implemented interfaces implementedInterfaces := make(map[string]AbiInterface) - fmt.Println("now parsing implemented interfaces") - implArray, ok := groupedAbi["impl"] - if !ok { - //return nil, errParseImplementedInterfaces - //this if block is not required - } + implArray, _ := groupedAbi["impl"] for _, implData := range implArray { implMap := implData if ifaceName, ok := implMap["interface_name"].(string); ok { @@ -171,19 +148,6 @@ func StarknetAbiFromJSON(abiJson []map[string]interface{}, abiName string, class } } } - fmt.Println("abi name : ", abiName) - fmt.Println("classhash is : ", classHash) - fmt.Println() - fmt.Println("functions is : ", functions) - fmt.Println() - fmt.Println("events is : ", events) - fmt.Println() - fmt.Println("constructor is : ", constructor) - fmt.Println() - fmt.Println("l1handles is ", l1Handler) - fmt.Println() - fmt.Println("implemented interfaces is : ", implementedInterfaces) - fmt.Println() // Return the populated StarknetAbi struct return &StarknetABI{ ABIName: &abiName, diff --git a/athena_abi/parse.go b/athena_abi/parse.go index 238ee040..dacc189e 100644 --- a/athena_abi/parse.go +++ b/athena_abi/parse.go @@ -2,7 +2,6 @@ package athena_abi import ( "fmt" - "reflect" "strings" ) @@ -11,20 +10,10 @@ func GroupAbiByType(abiJson []map[string]interface{}) map[AbiMemberType][]map[st grouped := make(map[AbiMemberType][]map[string]interface{}) for _, entry := range abiJson { - /*if entry["type"] == "struct" || entry["type"] == "enum" { - grouped["type_def"] = append(grouped["type_def"], entry) - } else { - grouped[AbiMemberType(typeStr)] = append(grouped[AbiMemberType(entry["type"])], entry) - - }*/ typeStr, _ := entry["type"].(string) - - // Convert the string to AbiMemberType if typeStr == "struct" || typeStr == "enum" { - fmt.Println("the types string value is ", typeStr) grouped["type_def"] = append(grouped["type_def"], entry) } else { - fmt.Println("the types string value is ", typeStr) grouped[AbiMemberType(typeStr)] = append(grouped[AbiMemberType(typeStr)], entry) } @@ -62,21 +51,11 @@ func extractInnerType(abiType string) string { // The function takes in a list of type definitions (dict) and returns a dict of sets (map[string]bool) func BuildTypeGraph(typeDefs []map[string]interface{}) map[string]map[string]bool { - fmt.Println() - fmt.Println("typdefs os ", typeDefs) - fmt.Println() - fmt.Println("the types of typdefs is ", reflect.TypeOf(typeDefs)) - fmt.Println() outputGraph := make(map[string]map[string]bool) for _, typeDef := range typeDefs { referencedTypes := []string{} - fmt.Println("the typedef is ", typeDef) - fmt.Println() - fmt.Println("the types of typdef is ", reflect.TypeOf(typeDef)) - fmt.Println() - fmt.Println("the type of typedef.member", reflect.TypeOf(typeDef["members"])) //here reflect.typeof() retunrs the inner type stored in the interface always if typeDef["type"] == "struct" { - for _, member := range typeDef["members"].([]map[string]interface{}) { //here this works as typeDef["members"] is of interface{} type not a slice of interface so a single type assertion will work + for _, member := range typeDef["members"].([]map[string]interface{}) { referencedTypes = append(referencedTypes, member["type"].(string)) } } else { @@ -136,7 +115,6 @@ func TopoSortTypeDefs(typeDefs []map[string]interface{}) ([]map[string]interface sortedTypeDefJson[i], sortedTypeDefJson[j] = sortedTypeDefJson[j], sortedTypeDefJson[i] } - // Return the reversed slice return sortedTypeDefJson, nil } @@ -161,8 +139,6 @@ func ParseEnumsAndStructs(abiStructs []map[string]interface{}) (map[string]inter switch abiStruct["type"] { case "struct": - fmt.Println("a") - fmt.Println("abistruct is", abiStruct) res, err := parseStruct(abiStruct, outputTypes) if err != nil { return nil, err @@ -170,7 +146,6 @@ func ParseEnumsAndStructs(abiStructs []map[string]interface{}) (map[string]inter outputTypes[typeName] = res case "enum": - fmt.Println("d") res, err := parseEnum(abiStruct, outputTypes) if err != nil { return nil, err @@ -184,13 +159,11 @@ func ParseEnumsAndStructs(abiStructs []map[string]interface{}) (map[string]inter func parseStruct(abiStruct map[string]interface{}, typeContext map[string]interface{}) (StarknetStruct, error) { members := []AbiParameter{} - // Assert that "members" is a slice of interfaces memberInterfaces, ok := abiStruct["members"].([]interface{}) if !ok { return StarknetStruct{}, fmt.Errorf("invalid type for members: expected []interface{}") } - // Iterate over the members and convert each to map[string]interface{} for _, memberInterface := range memberInterfaces { member, ok := memberInterface.(map[string]interface{}) if !ok { @@ -198,10 +171,8 @@ func parseStruct(abiStruct map[string]interface{}, typeContext map[string]interf } // Parse the member type - fmt.Println("b") - fmt.Println("thetypes are ", member["type"]) + res, err := parseType(member["type"].(string), typeContext) - fmt.Println("res is ", res) if err != nil { return StarknetStruct{}, err } @@ -265,21 +236,13 @@ func parseType(abiType string, customTypes map[string]interface{}) (StarknetType } if strings.HasPrefix(abiType, "(") { - fmt.Println("the abitype for parsetuple input is", abiType) res, err := ParseTuple(abiType, customTypes) - fmt.Println("the result afternparsing the tuple is ", res) if err != nil { return nil, err } return res, nil } - /*if strings.HasPrefix(abiType, "(") && strings.HasSuffix(abiType, ")") { - return ParseTuple(abiType, customTypes) - }*/ - fmt.Println("abitype is", abiType) parts := strings.Split(abiType, "::")[1:] - fmt.Println("c") - fmt.Println("the parts is ", parts) switch { case len(parts) == 1 && parts[0] == "felt252": @@ -297,7 +260,6 @@ func parseType(abiType string, customTypes map[string]interface{}) (StarknetType case len(parts) == 3 && parts[0] == "starknet" && parts[1] == "storage_access" && parts[2] == "StorageAddress": return StorageAddress, nil case len(parts) >= 2 && (parts[0] == "array" && parts[1] == "Array" || parts[1] == "Span"): - //case len(parts) >= 2 && parts[0] res, err := parseType(extractInnerType(abiType), customTypes) if err != nil { return nil, err @@ -323,12 +285,10 @@ func parseType(abiType string, customTypes map[string]interface{}) (StarknetType } return intType, nil default: - fmt.Println("the lenght of abitype in the default for v1 is ", len(abiType)) abiType := strings.TrimSpace(abiType) if val, exists := customTypes[abiType]; exists { return val.(StarknetType), nil } else if abiType == "felt" { - fmt.Println("this was run correctly") return Felt, nil } else if abiType == "Uint256" { return U256, nil @@ -339,7 +299,6 @@ func parseType(abiType string, customTypes map[string]interface{}) (StarknetType } return StarknetArray{res}, nil } else { - fmt.Println("hey hi this was executed and the value if abitype is ", abiType) return nil, &InvalidAbiError{ Msg: "Invalid ABI type: " + abiType, } @@ -366,9 +325,7 @@ func isNamedTuple(typeStr string) int { // customTypes is a map from string to StarknetStruct or StarknetEnum func ParseTuple(abiType string, customTypes map[string]interface{}) (StarknetTuple, error) { trimmed := strings.TrimSpace(abiType) - fmt.Println("trrimmed tuopls is", trimmed) strippedTuple := strings.TrimSpace(trimmed[1 : len(trimmed)-1]) - fmt.Println("stripped tuples is", strippedTuple) outputTypes := []StarknetType{} parenthesisCache := []string{} typeCache := []string{} @@ -394,7 +351,6 @@ func ParseTuple(abiType string, customTypes map[string]interface{}) (StarknetTup if err != nil { return StarknetTuple{}, err } - fmt.Print("the res in tuple parsing is", res) outputTypes = append(outputTypes, res) } } @@ -403,14 +359,12 @@ func ParseTuple(abiType string, customTypes map[string]interface{}) (StarknetTup if len(parenthesisCache) == 0 { res, err := ParseTuple(strings.Join(typeCache, ","), customTypes) if err != nil { - fmt.Println("error reported") return StarknetTuple{}, err } outputTypes = append(outputTypes, res) } } } - fmt.Println("the output in tuple parsing is ", outputTypes) return StarknetTuple{Members: outputTypes}, nil } @@ -430,7 +384,6 @@ func parseAbiParameters(names []string, types []string, customTypes map[string]i if err != nil { return nil, err } - fmt.Println("the res id qwerty", res) outputParameters = append(outputParameters, AbiParameter{ Name: names[i], Type: res, @@ -465,11 +418,8 @@ func ParseAbiTypes(types []string, customTypes map[string]interface{}) ([]Starkn func ParseAbiFunction(abiFunction map[string]interface{}, customTypes map[string]interface{}) (*AbiFunction, error) { names := []string{} types := []string{} - /*for _, abiInput := range abiFunction["inputs"].([]map[string]interface{}) { - names = append(names, abiInput["name"].(string)) - }*/ for _, abiInput := range abiFunction["inputs"].([]interface{}) { - inputMap := abiInput.(map[string]interface{}) // Assert each element as map[string]interface{} + inputMap := abiInput.(map[string]interface{}) names = append(names, inputMap["name"].(string)) } for _, abiInput := range abiFunction["inputs"].([]interface{}) { @@ -484,10 +434,6 @@ func ParseAbiFunction(abiFunction map[string]interface{}, customTypes map[string if err != nil { return nil, err } - - /*for _, abiOutput := range abiFunction["outputs"].([]map[string]interface{}) { - types = append(types, abiOutput["type"].(string)) - }*/ for _, abiOutput := range abiFunction["outputs"].([]interface{}) { outputMap := abiOutput.(map[string]interface{}) types = append(types, outputMap["type"].(string)) @@ -510,32 +456,18 @@ func ParseAbiFunction(abiFunction map[string]interface{}, customTypes map[string func ParseAbiEvent(abiEvent map[string]interface{}, customTypes map[string]interface{}) (*AbiEvent, error) { eventParameters := []map[string]interface{}{} - fmt.Print("the abievent is", abiEvent) if value, exists := abiEvent["kind"]; exists { if value == "struct" { - //eventParameters = abiEvent["members"].([]map[string]interface{}) - fmt.Println() - fmt.Println("abievent.members is ", abiEvent["members"]) - fmt.Println() - eventMembers := abiEvent["members"].([]interface{}) // Assert as []interface{} - fmt.Println("eventmembers is ", eventMembers) - fmt.Println() - //eventParameters := make([]map[string]interface{}, len(eventMembers)) + eventMembers := abiEvent["members"].([]interface{}) for _, member := range eventMembers { - fmt.Println("the memberbeing added is ", member) - fmt.Println("asdf if is running") - mem, _ := member.(map[string]interface{}) // Assert each element as map[string]interface{} + mem, _ := member.(map[string]interface{}) eventParameters = append(eventParameters, mem) - fmt.Println("the eventparameter status is ", eventParameters) } } else { - fmt.Println("asdf else is running") - fmt.Print("in parsig abi event the else1 nil was there") return nil, nil } } else if inputs, ok := abiEvent["inputs"].([]map[string]interface{}); ok { - fmt.Println("searching for inputs") for _, e := range inputs { eventParameter := map[string]interface{}{"kind": "data"} for k, v := range e { @@ -544,52 +476,29 @@ func ParseAbiEvent(abiEvent map[string]interface{}, customTypes map[string]inter eventParameters = append(eventParameters, eventParameter) } } else if data, ok := abiEvent["data"].([]interface{}); ok { - fmt.Println(ok) - fmt.Println("searching for data") var result []map[string]interface{} for _, item := range data { - fmt.Println("item is of type ", reflect.TypeOf(item)) - fmt.Println("result is of type ", reflect.TypeOf(result)) // Assert the type of item if m, ok := item.(map[string]interface{}); ok { result = append(result, m) - } else { - // Handle the case where the item is not of the expected type - fmt.Println("Item is not of type map[string]interface{}:", item) } } for _, e := range result { - fmt.Println(e) eventParameter := map[string]interface{}{"kind": "data"} for k, v := range e { eventParameter[k] = v } eventParameters = append(eventParameters, eventParameter) } - /*for _, e := range abiEvent["keys"].([]map[string]interface{}) { - eventParameter := map[string]interface{}{"kind": "key"} - for k, v := range e { - eventParameter[k] = v - } - eventParameters = append(eventParameters, eventParameter) - }*/ + if keys, ok := abiEvent["keys"].([]interface{}); ok { var keyres []map[string]interface{} - fmt.Println("keys is of type ", reflect.TypeOf(abiEvent["keys"])) - fmt.Println("result is of type ", reflect.TypeOf(result)) for _, key := range keys { - fmt.Println("item is of type ", reflect.TypeOf(key)) - fmt.Println("result is of type ", reflect.TypeOf(keyres)) - // Assert the type of item if m, ok := key.(map[string]interface{}); ok { keyres = append(keyres, m) - } else { - // Handle the case where the item is not of the expected type - fmt.Println("Item is not of type map[string]interface{}:", key) } } for _, e := range keyres { - fmt.Println(e) eventParameter := map[string]interface{}{"kind": "key"} for k, v := range e { eventParameter[k] = v @@ -599,26 +508,15 @@ func ParseAbiEvent(abiEvent map[string]interface{}, customTypes map[string]inter } } else { - fmt.Println("not found anything now in else") - //fmt.Println("the type is ", reflect.TypeOf(abiEvent["data"])) - //fmt.Println("the data is ", abiEvent["data"]) - fmt.Println("asdf else 3 is running") - data, ok := abiEvent["data"].([]map[string]interface{}) - fmt.Println("data is", data) - fmt.Println("ok is ", ok) - fmt.Print("in parsig abi event the else2 nil was there") return nil, nil } types := []string{} names := []string{} - fmt.Println("hey hey hey the value of eventparameters is ", eventParameters) for _, eventParameter := range eventParameters { types = append(types, eventParameter["type"].(string)) names = append(names, eventParameter["name"].(string)) } - fmt.Println("types is ", types) - fmt.Println("names is ", names) decodedParams, err := parseAbiParameters( names, types, diff --git a/athena_abi/parse_full_abi_test.go b/athena_abi/parse_full_abi_test.go index 4efb92d5..964b38f4 100644 --- a/athena_abi/parse_full_abi_test.go +++ b/athena_abi/parse_full_abi_test.go @@ -3,7 +3,6 @@ package athena_abi import ( "encoding/hex" "encoding/json" - "fmt" "testing" "github.com/stretchr/testify/assert" @@ -87,74 +86,15 @@ func TestLoadEthAbi(t *testing.T) { assert.Equal(t, "starknet_eth", *ethDecoder.ABIName, "ABI name should match") } -/*func TestLoadWildcardArraySyntax(t *testing.T) { - // Load the ABI - wildcardAbi, err := loadAbi("complex_array", 1) - assert.NoError(t, err, "Failed to load ABI") - - // Convert the hex string to bytes - classHash, err := hex.DecodeString("0031da92cf5f54bcb81b447e219e2b791b23f3052d12b6c9abd04ff2e5626576") - assert.NoError(t, err, "Failed to decode hex string") - - // Create the decoder using the from JSON function - decoder, err := StarknetAbiFromJSON(wildcardAbi, "complex_array", classHash) - assert.NoError(t, err, "Failed to create Starknet ABI from JSON") - - // Add assertions to verify the properties of `decoder` - // Example assertions (adjust according to expected values): - assert.NotNil(t, decoder, "Decoder should not be nil") - //assert.Equal(t, expectedValue, decoder.SomeProperty, "Unexpected value for SomeProperty") -} - - -func TestLoadWildcardArraySyntax(t *testing.T) { - wildcardAbi,err := loadAbi("complex_array", 1) - assert.NoError(t, err, "Loading ABI should not return an error") - // Decode the hex string directly - decodedClassHash, err := hex.DecodeString("0031da92cf5f54bcb81b447e219e2b791b23f3052d12b6c9abd04ff2e5626576") - assert.NoError(t, err, "Failed to decode hex string") - - decoder, err := StarknetAbiFromJSON( - wildcardAbi, - "complex_array", - decodedClassHash, - ) - assert.NoError(t, err, "Failed to decode ABI") - - parsedEvent := decoder.Events["log_storage_cells"] - - // Assert the length of parsed event data - assert.Len(t, parsedEvent.data, 1, "Expected parsed event data length to be 1") - - // Assert the storage_cells data matches the expected structure - assert.Equal(t, parsedEvent.data["storage_cells"], StarknetArray( - StarknetStruct{ - Name: "StorageCell", - Members: []AbiParameter{ - {Name: "key", Type: StarknetCoreType.Felt}, - {Name: "value", Type: StarknetCoreType.Felt}, - }, - }, - ), "Expected storage_cells data structure to match") - - // Assert the event name - assert.Equal(t, parsedEvent.Name, "log_storage_cells", "Expected event name to be 'log_storage_cells'") -} -*/ - func TestLoadWildcardArraySyntax(t *testing.T) { // Load the ABI (you'll need to implement this function) wildcardAbi, err := loadAbi("complex_array", 1) assert.NoError(t, err, "Loading ABI should not return an error") classHash, _ := hex.DecodeString("0031da92cf5f54bcb81b447e219e2b791b23f3052d12b6c9abd04ff2e5626576") - //fmt.Println("wildcard",wildcardAbi) decoder, err := StarknetAbiFromJSON(wildcardAbi, "complex_array", classHash) assert.NoError(t, err, "there should not be error") - fmt.Println("decoder is ", decoder) - fmt.Println("the err is ", err) parsedEvent, ok := decoder.Events["log_storage_cells"] - fmt.Println("parsedevent is ", parsedEvent) assert.True(t, ok, "Event 'log_storage_cells' should exist") assert.Equal(t, 1, len(parsedEvent.data), "Parsed event should have 1 data field") @@ -170,7 +110,6 @@ func TestLoadWildcardArraySyntax(t *testing.T) { assert.Equal(t, "StorageCell", structType.Name) assert.Equal(t, 2, len(structType.Members), "StorageCell struct should have 2 members") - fmt.Println("hello hello the val is ", structType.Members) assert.Equal(t, "key", structType.Members[0].Name) assert.Equal(t, StarknetCoreType(Felt), structType.Members[0].Type) @@ -262,15 +201,12 @@ func TestParseEventKeys(t *testing.T) { // Decode the ABI using StarknetAbiFromJSON parsedAbi, err := StarknetAbiFromJSON(abiJson, "erc20_key_events", classHash) - fmt.Println("parsedabi is helc ", parsedAbi) - fmt.Println("the err is helc ", err) assert.NoError(t, err, "Error parsing ABI for erc20_key_events") assert.NotNil(t, parsedAbi, "Parsed ABI should not be nil for erc20_key_events") // Access the "Approval" event from the parsed ABI approveEvent, ok := parsedAbi.Events["Approval"] assert.True(t, ok, "Approval event should be found in the parsed ABI") - fmt.Println("approve event ", approveEvent) // Validate the event's parameters expectedParameters := []string{"owner", "spender", "value"} assert.Equal(t, expectedParameters, approveEvent.parameters, "Expected parameters do not match") diff --git a/athena_abi/parse_struct_test.go b/athena_abi/parse_struct_test.go index f16b24b7..d3b290f2 100644 --- a/athena_abi/parse_struct_test.go +++ b/athena_abi/parse_struct_test.go @@ -36,7 +36,6 @@ func loadAbi(abiName string, abiVersion int) ([]map[string]interface{}, error) { if err != nil { return nil, fmt.Errorf("failed to decode ABI JSON: %w", err) } - //fmt.Println("Map contents:", abiJson) return abiJson, nil } func init() {