feat: changed peer id location#1138
Conversation
|
No actionable comments were generated in the recent review. 🎉 📝 WalkthroughWalkthroughPeer ID storage moved from the database to a file-based approach: startup now reads/writes a secp256k1 key at Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@crates/chain/src/chain.rs`:
- Around line 2195-2231: Run rustfmt (cargo fmt) to fix formatting issues in the
get_or_create_peer_id function; specifically reformat the block handling
key_path, the creation branch that defines signing_key, and the final peer_id
return so that spacing/line breaks around key_path.display(), signing_key, and
peer_id match project formatting. Ensure you run `cargo fmt` on the crate
(crates/chain) and recommit the changed formatting for the get_or_create_peer_id
function (references: get_or_create_peer_id, key_path, signing_key, peer_id).
- Around line 2216-2224: The private key is being created with std::fs::write
which may produce world-readable permissions; change the write to explicitly
create the file with owner-only permissions on Unix: open the key_path using
std::fs::OpenOptions (or OpenOptionsExt on Unix) and set mode to 0o600 when
creating, write key.to_bytes().as_slice() into that handle, and fallback to the
existing std::fs::write behavior on non-Unix via cfg(unix) so Windows semantics
are unchanged; update the block around peer_info_dir, key_path, and the key
write to use this secure create-and-write approach.
- Line 2205: The TOCTOU arises because the code checks key_path.exists() before
reading; change to a read-first pattern by attempting std::fs::read(&key_path)
and matching the result: on Ok(data) parse/deserialize to produce signing_key,
on Err(e) if e.kind() == std::io::ErrorKind::NotFound then handle the "missing
key" path (generate a new signing key, create parent dirs if needed, and write
it out), and for other errors return or log the I/O error. Update the logic
surrounding the signing_key variable and key_path usage (the block that
currently starts with let signing_key = if key_path.exists()) to use this
read-first approach.
- Around line 2205-2231: The code derives peer_id three times from the same
private key (inside both branches and again after the if/else); refactor to
derive peer_id once after obtaining signing_key: keep the existing logic that
reads or generates the SigningKey in the if/else (functions/values: key_path,
peer_info_dir, k256::ecdsa::SigningKey, signing_key), remove the duplicate
IrysPeerId::from(irys_types::IrysAddress::from_private_key(...)) calls inside
each branch, and compute let peer_id =
irys_types::IrysPeerId::from(irys_types::IrysAddress::from_private_key(&signing_key))
once after the if/else so you can use peer_id for logging and for the returned
Ok(peer_id).
| std::fs::create_dir_all(&peer_info_dir).with_context(|| { | ||
| format!( | ||
| "Failed to create peer info directory {}", | ||
| peer_info_dir.display() | ||
| ) | ||
| })?; | ||
| std::fs::write(&key_path, key.to_bytes().as_slice()).with_context(|| { | ||
| format!("Failed to write peer key to {}", key_path.display()) | ||
| })?; |
There was a problem hiding this comment.
Private key file written with default permissions — may be world-readable.
std::fs::write uses the OS default umask, which on many Linux systems means the file is created with 0644 (world-readable). Since this is a private key that constitutes the node's P2P identity, it should be restricted to owner-only access.
🔒 Proposed fix: set restrictive permissions on Unix
std::fs::write(&key_path, key.to_bytes().as_slice()).with_context(|| {
format!("Failed to write peer key to {}", key_path.display())
})?;
+ #[cfg(unix)]
+ {
+ use std::os::unix::fs::PermissionsExt;
+ std::fs::set_permissions(&key_path, std::fs::Permissions::from_mode(0o600))
+ .with_context(|| {
+ format!("Failed to set permissions on {}", key_path.display())
+ })?;
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| std::fs::create_dir_all(&peer_info_dir).with_context(|| { | |
| format!( | |
| "Failed to create peer info directory {}", | |
| peer_info_dir.display() | |
| ) | |
| })?; | |
| std::fs::write(&key_path, key.to_bytes().as_slice()).with_context(|| { | |
| format!("Failed to write peer key to {}", key_path.display()) | |
| })?; | |
| std::fs::create_dir_all(&peer_info_dir).with_context(|| { | |
| format!( | |
| "Failed to create peer info directory {}", | |
| peer_info_dir.display() | |
| ) | |
| })?; | |
| std::fs::write(&key_path, key.to_bytes().as_slice()).with_context(|| { | |
| format!("Failed to write peer key to {}", key_path.display()) | |
| })?; | |
| #[cfg(unix)] | |
| { | |
| use std::os::unix::fs::PermissionsExt; | |
| std::fs::set_permissions(&key_path, std::fs::Permissions::from_mode(0o600)) | |
| .with_context(|| { | |
| format!("Failed to set permissions on {}", key_path.display()) | |
| })?; | |
| } |
🧰 Tools
🪛 GitHub Check: cargo fmt
[warning] 2219-2219:
Diff in /home/runner/actions-runner/_work/irys/irys/crates/chain/src/chain.rs
🤖 Prompt for AI Agents
In `@crates/chain/src/chain.rs` around lines 2216 - 2224, The private key is being
created with std::fs::write which may produce world-readable permissions; change
the write to explicitly create the file with owner-only permissions on Unix:
open the key_path using std::fs::OpenOptions (or OpenOptionsExt on Unix) and set
mode to 0o600 when creating, write key.to_bytes().as_slice() into that handle,
and fallback to the existing std::fs::write behavior on non-Unix via cfg(unix)
so Windows semantics are unchanged; update the block around peer_info_dir,
key_path, and the key write to use this secure create-and-write approach.
There was a problem hiding this comment.
This is fine, it's not used for anything - it's just there just in case, in fact we were throwing it out before
There was a problem hiding this comment.
@antouhou, understood! Thank you for the clarification. If the peer key isn't used for security-critical operations and was being regenerated before, then the default file permissions are perfectly fine.
✏️ Learnings added
Learnt from: antouhou
Repo: Irys-xyz/irys PR: 1138
File: crates/chain/src/chain.rs:2216-2224
Timestamp: 2026-02-13T20:39:55.498Z
Learning: In the Irys repository, the peer key file (`<peer_info_dir>/peer_key.bin`) used for deriving the P2P PeerId does not require restrictive file permissions (e.g., 0o600), as it is not used for security-critical operations and was previously regenerated/not persisted permanently.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: glottologist
Repo: Irys-xyz/irys PR: 1074
File: docker/configs/irys-2.toml:4-5
Timestamp: 2026-01-16T11:57:20.272Z
Learning: In the Irys repository, hardcoded test mining keys and reward addresses in docker/configs/*.toml files (e.g., docker/configs/irys-1.toml, docker/configs/irys-2.toml) are intentional and should not be flagged, even though they appear to be realistic hex values. These files already include `#changeme` comments to indicate they are placeholders.
Describe the changes
This PR moves peer id from the DB to a file, so we can have cleaner snapshots
Related Issue(s)
Checklist
Additional Context
Summary by CodeRabbit