-
Notifications
You must be signed in to change notification settings - Fork 32
fix: make start node test friendly and fix several memory leak #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Chen Kai <281165273grape@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the node architecture to make it more testing-friendly by introducing a proper Node struct that encapsulates all components and provides explicit lifecycle management. The changes also address memory leaks by adding deinit methods throughout the codebase.
- Transforms the standalone
startNodefunction into aNodestruct with clear initialization and cleanup methods - Adds comprehensive deinit methods to prevent memory leaks across multiple components
- Improves ownership management for allocated resources like network addresses and callback wrappers
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pkgs/types/src/lib.zig | Adds deinit method to BeamState for cleaning up allocated slices |
| pkgs/node/src/node.zig | Adds deinit method to BeamNode for proper chain cleanup |
| pkgs/node/src/clock.zig | Adds deinit method to Clock for timer and callback cleanup |
| pkgs/node/src/chain.zig | Adds deinit method to BeamChain for states HashMap cleanup |
| pkgs/network/src/ethlibp2p.zig | Adds deinit method to EthLibp2p for address cleanup |
| pkgs/cli/src/node.zig | Major refactor introducing Node struct and moving ownership management |
| pkgs/cli/src/metrics_server.riz | Adds cleanup for metrics server allocation |
| pkgs/cli/src/main.zig | Updates to use new Node struct API |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
pkgs/cli/src/node.zig
Outdated
|
|
||
| var node_multiaddrs = try self.enr.multiaddrP2PQUIC(allocator); | ||
| defer node_multiaddrs.deinit(allocator); | ||
| // move the ownership to the `EthLibp2p`, will be freed in its deinit |
Copilot
AI
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] These comments about ownership transfer are helpful but could be more specific about what happens if the EthLibp2p initialization fails after ownership transfer. Consider documenting the cleanup responsibility in case of initialization failure.
| // move the ownership to the `EthLibp2p`, will be freed in its deinit | |
| // Ownership of `listen_addresses` is transferred to `EthLibp2p` and will be freed in its deinit. | |
| // If EthLibp2p initialization fails after this point, the caller is responsible for freeing | |
| // `listen_addresses` to avoid a memory leak. |
pkgs/cli/src/node.zig
Outdated
| } | ||
| } | ||
|
|
||
| // move the ownership to the `EthLibp2p`, will be freed in its deinit |
Copilot
AI
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] These comments about ownership transfer are helpful but could be more specific about what happens if the EthLibp2p initialization fails after ownership transfer. Consider documenting the cleanup responsibility in case of initialization failure.
| // move the ownership to the `EthLibp2p`, will be freed in its deinit | |
| // Ownership of `connect_peers` is transferred to `EthLibp2p` and will be freed in its deinit. | |
| // If `EthLibp2p` initialization fails after this point, the caller is responsible for freeing `connect_peers`. |
pkgs/cli/src/node.zig
Outdated
|
|
||
| self.clock = try Clock.init(allocator, chain_config.genesis.genesis_time, &self.loop); | ||
|
|
||
| const beam_node = try BeamNode.init(allocator, .{ |
Copilot
AI
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The variable beam_node is only used to assign to self.beam_node. Consider directly assigning the result of BeamNode.init to self.beam_node to eliminate the intermediate variable.
pkgs/cli/src/node.zig
Outdated
| .logger = options.logger, | ||
| }); | ||
|
|
||
| self.beam_node = beam_node; |
Copilot
AI
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The variable beam_node is only used to assign to self.beam_node. Consider directly assigning the result of BeamNode.init to self.beam_node to eliminate the intermediate variable.
| port: u16, | ||
|
|
||
| fn run(self: *SimpleMetricsServer) !void { | ||
| // `startMetricsServer` creates this, so we need to free it here |
Copilot
AI
Sep 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The comment references startMetricsServer but this function name is not visible in the current diff context. Consider making the comment more explicit about where this allocation occurs or use a more generic description.
| // `startMetricsServer` creates this, so we need to free it here | |
| // This struct was heap-allocated and must be freed here to avoid memory leaks |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| // historical_block_hashes and justified_slots are slices so need to be freed | ||
| // justifications_roots and justifications_validators not freed for now as they are not allocated | ||
| allocator.free(self.historical_block_hashes); | ||
| allocator.free(self.justified_slots); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need a ssz.deinit which frees all the slices/allocated stuff recursively, so its better to add that and use that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These seems not managed by ssz, ssz returns the ownership to caller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I remembered the types ser/dser using ssz lib can't have allocator field, since the ssz lib will reflect all the fields in the types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am not asking it to be managed by ssz, I am asking to add a recursive freeing fn, similar to how serialize
like : sszFree(T: type, object: T)
and free if any slices, lists there recurisvely because the shape of the objects will change so its better implemented as a generic ssz free/denit fn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may need more consider as not all the slices allocated such as justifications_roots and justifications_validators. It is better to create a specific issue for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed this is a bigger issue and needs to be addressed in ssz as well where slices also need to come from toOwnedSlice, and then a sszFree needs to recursively free slices. @noopur23 create an issue on blockblaz/ssz.zig repo for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually this slice freeing will become irrelevant because we are working on a PR to replace it by ssz list,
@noopur23 add another task in zeam to add "deinit" functions to all ssz types which will use the sszFree fn to be created in ssz lib as above
Signed-off-by: Chen Kai <281165273grape@gmail.com>
Signed-off-by: Chen Kai <281165273grape@gmail.com>
|
|
||
| const Self = @This(); | ||
|
|
||
| pub fn init(self: *Self, allocator: std.mem.Allocator, options: *const NodeOptions) !void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a weird form of init where one passes the reference to a self which is unitialized
need @gballet 's opinion on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a general and better approach in Zig. https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md#cache-invalidation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, then we need to move a whole lot of inits to this form
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think it also depends on how large the struct is as the link mentions, if the struct isn't large in size then this form is not necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, most of structs in node pkgs are large
|
|
||
| const ascii_art = | ||
| \\ | ||
| \\ ███████╗███████╗ █████╗ ███╗ ███╗ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool art ❤️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can probably also ascii convert our logo and add it suitably, @noopur23 create an issue for this
Signed-off-by: Chen Kai <281165273grape@gmail.com>
g11tech
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
…blaz#198) * fix: make start node test friendly and fix several memory leak Signed-off-by: Chen Kai <281165273grape@gmail.com> * Update pkgs/types/src/lib.zig Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: fix more memory leak when error Signed-off-by: Chen Kai <281165273grape@gmail.com> * fix: fix one more error meory leak Signed-off-by: Chen Kai <281165273grape@gmail.com> * Update pkgs/cli/src/node.zig * Update pkgs/cli/src/main.zig * fix: flattening order (blockblaz#208) * update sig size to 4000 bytes as per spec (blockblaz#210) * fix: abstract away network args into a function Signed-off-by: Chen Kai <281165273grape@gmail.com> --------- Signed-off-by: Chen Kai <281165273grape@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: g11tech <develop@g11tech.io> Co-authored-by: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Co-authored-by: g11tech <gajinder@zeam.in>
* fix: make start node test friendly and fix several memory leak (#198) * fix: make start node test friendly and fix several memory leak Signed-off-by: Chen Kai <281165273grape@gmail.com> * Update pkgs/types/src/lib.zig Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: fix more memory leak when error Signed-off-by: Chen Kai <281165273grape@gmail.com> * fix: fix one more error meory leak Signed-off-by: Chen Kai <281165273grape@gmail.com> * Update pkgs/cli/src/node.zig * Update pkgs/cli/src/main.zig * fix: flattening order (#208) * update sig size to 4000 bytes as per spec (#210) * fix: abstract away network args into a function Signed-off-by: Chen Kai <281165273grape@gmail.com> --------- Signed-off-by: Chen Kai <281165273grape@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: g11tech <develop@g11tech.io> Co-authored-by: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Co-authored-by: g11tech <gajinder@zeam.in> * refactor: abstract help fn for justifications Fix #182 * fix: fix review comments Signed-off-by: Chen Kai <281165273grape@gmail.com> * fix: resolve merge issue Signed-off-by: Chen Kai <281165273grape@gmail.com> * fix: fix merge error Signed-off-by: Chen Kai <281165273grape@gmail.com> * fix: make justifications deinit more explict Signed-off-by: Chen Kai <281165273grape@gmail.com> * free justifications values * spacing * fix log spacing --------- Signed-off-by: Chen Kai <281165273grape@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: g11tech <develop@g11tech.io> Co-authored-by: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Co-authored-by: g11tech <gajinder@zeam.in>
This PR makes starting node more testing friendly. Such as #194 it need access
BeamNodeto check finalize, but right now can't do it withstartNodefunction in thenode.zig. At the same time the refactor seems makeClock,BeamNodelifecycle more easy. Also try to fix some potential memory leak issue.