# EPF6 - Week 11 Updates ## tl;dr - My first [PR](https://github.com/OffchainLabs/prysm/pull/15588) is now merged! - Opened a follow-up [PR](https://github.com/OffchainLabs/prysm/pull/15637) for handling `List` type. ## Details ### Merging the first PR After PR reviewing process, my first [PR](https://github.com/OffchainLabs/prysm/pull/15588) got successfully merged into the Prysm repository (which is super cool!). This PR would work like a cornerstone for our subsequent works, so that Nando and I can push our project much forward. ![image](https://hackmd.io/_uploads/S120Wjzcgg.png) It's such an honor for me to contribute to Prysm since last year. Just wanted to share this! :+1: ### Subsequent PRs are on the track...! One of main challenge for SSZ-QL project is handling a variable-sized SSZ types. Unlike fixed-size types like `Vector`, the SSZ-QL engine cannot know the exact size of `List`, `Bitlist`, and `Container` with variable-sized typed fields before runtime. To resolve this issue, I wrote a function for "populating" the size information with an actual value (`PopulateVariableLengthInfo`). ```go! // PopulateVariableLengthInfo populates runtime information for SSZ fields of variable-sized types. // This function updates the sszInfo structure with actual lengths and offsets that can only // be determined at runtime for variable-sized items like Lists and variable-sized Container fields. func PopulateVariableLengthInfo(sszInfo *sszInfo, value any) error { if sszInfo == nil { return errors.New("sszInfo is nil") } if value == nil { return errors.New("value is nil") } // Short circuit: If the type is fixed-sized, we don't need to fill in the info. if !sszInfo.isVariable { return nil } switch sszInfo.sszType { // In List case, we have to set the actual length of the list. case List: listInfo, err := sszInfo.ListInfo() if err != nil { return fmt.Errorf("could not get list info: %w", err) } if listInfo == nil { return errors.New("listInfo is nil") } val := reflect.ValueOf(value) if val.Kind() != reflect.Slice { return fmt.Errorf("expected slice for List type, got %v", val.Kind()) } length := uint64(val.Len()) if err := listInfo.SetLength(length); err != nil { return fmt.Errorf("could not set list length: %w", err) } return nil // In Container case, we need to recursively populate variable-sized fields. case Container: containerInfo, err := sszInfo.ContainerInfo() if err != nil { return fmt.Errorf("could not get container info: %w", err) } // Dereference first in case value is a pointer. derefValue := dereferencePointer(value) // Start with the fixed size of this Container. currentOffset := sszInfo.FixedSize() for _, fieldName := range containerInfo.order { fieldInfo := containerInfo.fields[fieldName] childSszInfo := fieldInfo.sszInfo if childSszInfo == nil { return fmt.Errorf("sszInfo is nil for field %s", fieldName) } // Skip fixed-size fields. if !childSszInfo.isVariable { continue } // Set the actual offset for variable-sized fields. fieldInfo.offset = currentOffset // Recursively populate variable-sized fields. fieldValue := derefValue.FieldByName(fieldInfo.goFieldName) if err := PopulateVariableLengthInfo(childSszInfo, fieldValue.Interface()); err != nil { return fmt.Errorf("could not populate from value for field %s: %w", fieldName, err) } currentOffset += childSszInfo.Size() } return nil default: return fmt.Errorf("unsupported SSZ type (%s) for variable size info", sszInfo.sszType) } } ``` The function currently supports only two types, and supporting `Bitlist` is one of the other task to do. {%preview https://github.com/OffchainLabs/prysm/pull/15637 %} This PR introduces the populating function, with new test case for variable-sized types. As `List` is one of the most common data type in the Ethereum world, I believe this work can be applicable to many SSZ objects that we use everyday in CL. My mentor is on vacation in next week, so I'm planning to keep coding based on the PR above, and then rebase it after it is merged in Prysm codebase.