Skip to content

feat: Implement eth2util/deposit - #134

Merged
iamquang95 merged 19 commits into
mainfrom
iamquang95/eth2util/deposit2
Jan 30, 2026
Merged

iamquang95 merged 19 commits into
mainfrom
iamquang95/eth2util/deposit2

Conversation

@iamquang95

Copy link
Copy Markdown
Collaborator

Should fix: #63

@varex83 varex83 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Putting the first part of the review here, will check other part later

Comment thread crates/charon-eth2/src/deposit/constants.rs
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/errors.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
}

/// Serializes a list of deposit data into a single file.
pub fn marshal_deposit_data(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it should be replaced using serde and serde_json

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The DepositDataJson itself use serde as the serialize/deserialize. This method contains the transformation from input to serde-able datastructure. I don't like the name marshal, but decided to keep it to compatible with golang API for the first phase

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I agree with @varex83. Ideally this would be done at the serde level.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not sure if I understand correctly, but I'm not sure how can I implement this at serde level.

The function needs to take network as an argument to get fork_version and sign on that. If we want to write a Serialization we need to wrap the DepositData to DepositDataWithNetwork and impl Serialize trait for that. But it's quite over-engineering from my point of view.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think it will be over-engineering. From my point of view it would be just more rust idiomatic and will work natively with serde (which I would expect as a developer working on serialization/deserialization in rust)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Now that you mention the extra parameter, your solution seems like the right approach but I agree on the overengineering comment.

Let's leave it as it is for now then.

Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/helpers.rs Outdated
Comment thread crates/charon-eth2/src/helpers.rs Outdated
Comment thread crates/charon-eth2/src/deposit/types.rs Outdated
Comment thread crates/charon-eth2/src/deposit/types.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
}

/// Serializes a list of deposit data into a single file.
pub fn marshal_deposit_data(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I agree with @varex83. Ideally this would be done at the serde level.

Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/errors.rs Outdated
Comment thread crates/charon-eth2/src/deposit/constants.rs Outdated

@emlautarom1 emlautarom1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

Before merging, I suggest to evaluate if we can replace some of our code (in particular helpers) with methods provided by alloy

Comment thread crates/eth2util/src/deposit/mod.rs
Comment on lines +238 to +242
tokio::fs::write(&file_path, bytes).await?;

let mut perms = tokio::fs::metadata(&file_path).await?.permissions();
perms.set_readonly(true);
tokio::fs::set_permissions(&file_path, perms).await?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

File could be modified between write and permission change. I think we can check file hash before / after or use some kind of atomic operations instead.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

But it should be fine right? We read a snapshot of the permissions, and then write a modified version of the snapshot. If something happens to the file (ex. gets deleted) then the operation fails.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I mean that we set file to read-only, but the contents of it could be changed between write and permissions update

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm, makes sense. Let's follow what the Go implementation does and add a TODO here in case they don't do it atomically.

let mut deposit_datas_list = Vec::new();

for file in files {
let bytes = tokio::fs::read(&file).await?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Currently files are read sequentially, consider using FuturesUnordered

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Potential optimization, but the original Go code performs this operation sequentially.

Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
}

/// Reads all deposit data files from a cluster directory.
pub async fn read_deposit_data_files(cluster_dir: &Path) -> Result<Vec<Vec<DepositData>>> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
pub async fn read_deposit_data_files(cluster_dir: &Path) -> Result<Vec<Vec<DepositData>>> {
pub async fn read_deposit_data_files(cluster_dir: impl AsRef<Path>) -> Result<Vec<Vec<DepositData>>> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there any lint that we can use for this? Seems to be a recurring topic in our reviews

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Seems like adding pedantic = "warn" to [workspace.lints.clippy] adds a lot of good suggestions, I think we can use it

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It would be nice to have immediate feedback on the IDE rather than waiting for Copilot to review it, but as a fall-back that's OK too.

Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
Comment thread crates/charon-eth2/src/deposit/mod.rs Outdated
@iamquang95
iamquang95 requested a review from varex83 January 30, 2026 07:51

@varex83 varex83 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +726 to +732
async fn read_deposit_data_files_invalid_pubkey_hex() {
let dir = tempdir().unwrap();
let datas = generate_deposit_datas(DEFAULT_DEPOSIT_AMOUNT);
let bytes = marshal_deposit_data(&datas, "goerli").unwrap();
let file = get_deposit_file_path(dir.path(), DEFAULT_DEPOSIT_AMOUNT);
tokio::fs::write(&file, &bytes).await.unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since we have a lot of code duplication here I would suggest using test_case or something similar

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

That looks cleaner, will try to adopt it later 👍

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

See: #98

@iamquang95
iamquang95 merged commit ad2d221 into main Jan 30, 2026
4 checks passed
@iamquang95
iamquang95 deleted the iamquang95/eth2util/deposit2 branch January 30, 2026 15:51
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.

Implement eth2util/deposit

3 participants