Skip to content

Conversation

@GrapeBaBa
Copy link
Member

This PR makes starting node more testing friendly. Such as #194 it need access BeamNode to check finalize, but right now can't do it with startNode function in the node.zig. At the same time the refactor seems make Clock, BeamNode lifecycle more easy. Also try to fix some potential memory leak issue.

Signed-off-by: Chen Kai <281165273grape@gmail.com>
@GrapeBaBa GrapeBaBa requested review from bomanaps, Copilot, g11tech and gballet and removed request for bomanaps, Copilot and g11tech September 17, 2025 04:44
Copy link
Contributor

Copilot AI left a 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 startNode function into a Node struct 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.


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
Copy link

Copilot AI Sep 17, 2025

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.

Suggested change
// 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.

Copilot uses AI. Check for mistakes.
}
}

// move the ownership to the `EthLibp2p`, will be freed in its deinit
Copy link

Copilot AI Sep 17, 2025

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.

Suggested change
// 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`.

Copilot uses AI. Check for mistakes.

self.clock = try Clock.init(allocator, chain_config.genesis.genesis_time, &self.loop);

const beam_node = try BeamNode.init(allocator, .{
Copy link

Copilot AI Sep 17, 2025

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.

Copilot uses AI. Check for mistakes.
.logger = options.logger,
});

self.beam_node = beam_node;
Copy link

Copilot AI Sep 17, 2025

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.

Copilot uses AI. Check for mistakes.
port: u16,

fn run(self: *SimpleMetricsServer) !void {
// `startMetricsServer` creates this, so we need to free it here
Copy link

Copilot AI Sep 17, 2025

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.

Suggested change
// `startMetricsServer` creates this, so we need to free it here
// This struct was heap-allocated and must be freed here to avoid memory leaks

Copilot uses AI. Check for mistakes.
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);
Copy link
Member

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

Copy link
Member Author

@GrapeBaBa GrapeBaBa Sep 17, 2025

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.

Copy link
Member Author

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.

Copy link
Member

@g11tech g11tech Sep 17, 2025

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

Copy link
Member Author

@GrapeBaBa GrapeBaBa Sep 18, 2025

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.

Copy link
Member

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

Copy link
Member

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 {
Copy link
Member

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

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

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.

Copy link
Member

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 =
\\
\\ ███████╗███████╗ █████╗ ███╗ ███╗
Copy link
Member

Choose a reason for hiding this comment

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

cool art ❤️

Copy link
Member

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

@GrapeBaBa GrapeBaBa requested a review from g11tech September 18, 2025 15:35
Copy link
Member

@g11tech g11tech left a comment

Choose a reason for hiding this comment

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

lgtm

@g11tech g11tech merged commit fb0905b into blockblaz:main Sep 18, 2025
6 checks passed
GrapeBaBa added a commit to GrapeBaBa/zeam that referenced this pull request Sep 19, 2025
…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>
g11tech added a commit that referenced this pull request Sep 21, 2025
* 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>
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.

4 participants