Skip to content

Conversation

@ensi321
Copy link
Contributor

@ensi321 ensi321 commented Oct 21, 2025

Currently getElement and getField call will mark child dirty whether child is modified or not since parent has no visibility to track it.

Pass parent's data.changed and child's gindex to child TreeView, so when child is modified, parent can keep track of the changes.

@gemini-code-assist
Copy link

Summary of Changes

Hello @ensi321, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the TreeView's internal state management by implementing a more precise change tracking system. Previously, accessing child elements could inadvertently flag them as modified. The update introduces a parent_change context, enabling child TreeViews to accurately report modifications back to their parent, ensuring that only genuinely altered parts of the tree are marked, which improves efficiency and correctness.

Highlights

  • Refined Change Tracking: Introduced a mechanism to only mark child TreeView instances as changed if they are actually modified, resolving an issue where getElement and getField calls would unconditionally mark them dirty.
  • Parent Change Propagation: TreeView now carries a parent_change context, allowing child TreeView instances to notify their parent's data.changed map when they are modified.
  • New markChildChanged Function: A dedicated inline function markChildChanged centralizes the logic for updating both the current TreeView's data.changed and its parent's data.changed map.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly addresses the issue of getElement and getField unnecessarily marking child nodes as dirty. The introduction of the ParentChange struct and the markChildChanged function is a good approach to propagate the dirty status up the tree only upon actual modification.

However, I've identified a critical pre-existing issue with how sub-views are handled. When getElement or getField returns a TreeView, it contains a copy of the child's Data struct. Any subsequent modifications on this sub-view (e.g., using setElement or setField) are made to this copy and are lost when the sub-view goes out of scope. While the change is propagated to the parent's changed map, the actual data modification within the sub-view is not persisted, which means it won't be included in a commit.

For the TreeView API to work as expected for modifications on nested structures, TreeView should likely hold a pointer to its Data (data: *Data) rather than an instance (data: Data). This would ensure that all views of a certain piece of data are modifying the same instance. This would be a larger refactoring but is crucial for the correctness of modifying nested data. I've added specific comments where this issue occurs.

return TreeView(ST.Element){
.allocator = self.allocator,
.pool = self.pool,
.data = child_data,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This line copies the child_data struct into the new TreeView. This leads to a critical issue: any modifications made to the returned sub-view (e.g., by calling setElement or setField on it) are applied to this temporary copy and are lost when the view goes out of scope.

While the new parent_change mechanism correctly marks the parent as dirty, the actual data change within the sub-view is not persisted in the parent's children_data cache. Consequently, when commit is called on the parent, the sub-view's changes are not included.

To fix this, TreeView should probably hold a pointer to Data (data: *Data) instead of a value (data: Data). This would ensure that sub-views modify the shared Data instance stored in the parent's cache.

return TreeView(ChildST){
.allocator = self.allocator,
.pool = self.pool,
.data = child_data,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Similar to getElement, this line copies the child_data struct, which means any modifications on the returned TreeView are made on a temporary copy and will be lost.

This is a critical issue for correctness, as it prevents modifications to nested data structures from being persisted and committed. For the API to function as expected, TreeView should likely manage its Data via a pointer (data: *Data) to ensure all views operate on a shared data instance.

Copy link
Contributor

@twoeths twoeths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the solution may work but I found it pretty complex, since right now the design is top-down (parent tracks child data) and this introduces bottom-up approach
note that our js version handles this by doing very cheap comparision here https://github.com/ChainSafe/ssz/blob/7f5580c2ea69f9307300ddb6010a8bc7ce2fc471/packages/ssz/src/viewDU/container.ts#L103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants