Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7978ad0
Feat: Adding message_types.rs
ch4r10t33r Aug 31, 2025
dcf8b61
feat: parallelise key generation
ch4r10t33r Aug 31, 2025
6771ad2
feat: amended generate_keys function to create multiple keys based on…
ch4r10t33r Aug 31, 2025
9021822
fix: resolved udeps error
ch4r10t33r Aug 31, 2025
c3712de
feat: Added struct definitions for post quantum keystore
ch4r10t33r Sep 1, 2025
259be58
feat: Saving to QsKeystore
ch4r10t33r Sep 1, 2025
2737548
feat: Added passphrase parameter to account_manager command
ch4r10t33r Sep 2, 2025
d18c60c
Merge branch 'master' into account_manager
ch4r10t33r Sep 14, 2025
cdbaba7
fix: review comments
ch4r10t33r Sep 14, 2025
4ba922c
fix: fixed cargo fmt issue
ch4r10t33r Sep 14, 2025
1731b6d
fix: removed ascii art
ch4r10t33r Sep 17, 2025
dc65161
fix: fixed review comments
ch4r10t33r Sep 17, 2025
193b96c
Merge branch 'master' into account_manager
ch4r10t33r Sep 17, 2025
424a8ff
Fix: addressed review comments.
ch4r10t33r Sep 17, 2025
9660a93
Fix: review comment fixes
ch4r10t33r Sep 17, 2025
949091e
fix: linting errors
ch4r10t33r Sep 17, 2025
75a18f1
Fix: Update bin/ream/src/main.rs
ch4r10t33r Sep 17, 2025
5f4321b
Fix: Update crates/common/account_manager/src/keystore.rs
ch4r10t33r Sep 17, 2025
638959f
Fix: Update crates/common/account_manager/src/keystore.rs
ch4r10t33r Sep 17, 2025
4aa6fe9
Fix: review comment fixes
ch4r10t33r Sep 17, 2025
54b3a14
Merge branch 'account_manager' of https://github.com/ch4r10t33r/ream …
ch4r10t33r Sep 17, 2025
861c390
fix: fixed issues with build and removed redundant code
ch4r10t33r Sep 17, 2025
d43a7b4
Fix: review comment fixes
ch4r10t33r Sep 17, 2025
f12db7b
fix: Update bin/ream/src/cli/account_manager.rs
ch4r10t33r Sep 17, 2025
6da008b
Fix: Update bin/ream/src/cli/account_manager.rs
ch4r10t33r Sep 17, 2025
9ef714f
fix: Update crates/common/account_manager/src/lib.rs
ch4r10t33r Sep 17, 2025
7c03e53
Fix: Update crates/common/account_manager/src/message_types.rs
ch4r10t33r Sep 17, 2025
bfe8f5e
Fix: updated code to address comments
ch4r10t33r Sep 17, 2025
4c07a12
fix: review comment fixes
ch4r10t33r Sep 17, 2025
2269d17
fix: Removed parallel processing.
ch4r10t33r Sep 19, 2025
a2e260d
Fix: Removed rayon from Cargo.toml
ch4r10t33r Sep 19, 2025
7c307b9
Fix: addressed review comments
ch4r10t33r Sep 19, 2025
3f513b7
fix: renamed functions
ch4r10t33r Sep 19, 2025
eb82dd9
fix: changed the default keystore path
ch4r10t33r Sep 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ testing/ef-tests/mainnet/*

# DS_Store: Desktop Services Store
.DS_Store

# keystore
.keystore
56 changes: 50 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ alloy-rpc-types-beacon = "1.0.8"
alloy-rpc-types-eth = "1.0.7"
anyhow = "1.0"
async-trait = "0.1.86"
bip32 = "0.5.3"
bip39 = "2.2.0"
clap = "4"
delay_map = "0.4.1"
directories = { version = "6.0.0" }
Expand All @@ -86,6 +86,7 @@ eventsource-client = "0.15.0"
futures = "0.3"
hashbrown = "0.15.3"
hashsig = { git = "https://github.com/b-wagn/hash-sig", rev = "287517a763edba7e518b0c1ee5beb868f26f1f66" }
hex = "0.4"
itertools = "0.14"
jsonwebtoken = "9.3.1"
kzg = { git = "https://github.com/grandinetech/rust-kzg" }
Expand Down
1 change: 1 addition & 0 deletions bin/ream/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ path = "src/main.rs"
[dependencies]
alloy-primitives.workspace = true
anyhow.workspace = true
bip39.workspace = true
clap = { workspace = true, features = ["derive", "env"] }
discv5.workspace = true
hashbrown.workspace = true
Expand Down
39 changes: 30 additions & 9 deletions bin/ream/src/cli/account_manager.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use anyhow::ensure;
use bip39::Mnemonic;
use clap::Parser;
use tracing::info;

const MIN_CHUNK_SIZE: u64 = 4;
const MIN_LIFETIME: u64 = 18;
const DEFAULT_ACTIVATION_EPOCH: usize = 0;
const DEFAULT_NUM_ACTIVE_EPOCHS: usize = 1 << 18;
const MIN_CHUNK_SIZE: u32 = 4;
const MIN_LIFETIME: u32 = 18;
const DEFAULT_ACTIVATION_EPOCH: u32 = 0;
const DEFAULT_NUM_ACTIVE_EPOCHS: u32 = 1 << 18;
const DEFAULT_KEYSTORE_PATH: &str = "./.keystore/";

#[derive(Debug, Parser)]
pub struct AccountManagerConfig {
Expand All @@ -14,23 +17,31 @@ pub struct AccountManagerConfig {

/// Account lifetime in 2 ** lifetime slots
#[arg(short, long, default_value_t = 18)]
pub lifetime: u64,
pub lifetime: u32,

/// Chunk size for messages
#[arg(short, long, default_value_t = 5)]
pub chunk_size: u64,
pub chunk_size: u32,

/// Seed phrase for key generation
#[arg(short, long)]
pub seed_phrase: Option<String>,

/// Optional BIP39 passphrase used with the seed phrase
#[arg(long)]
pub passphrase: Option<String>,

/// Activation epoch for the validator
#[arg(long, default_value_t = DEFAULT_ACTIVATION_EPOCH)]
pub activation_epoch: usize,
pub activation_epoch: u32,

/// Number of active epochs
#[arg(long, default_value_t = DEFAULT_NUM_ACTIVE_EPOCHS)]
pub num_active_epochs: usize,
pub num_active_epochs: u32,

/// Path for keystore directory
#[arg(long, default_value = DEFAULT_KEYSTORE_PATH)]
pub path: String,
}

impl Default for AccountManagerConfig {
Expand All @@ -40,8 +51,10 @@ impl Default for AccountManagerConfig {
lifetime: 18,
chunk_size: 5,
seed_phrase: None,
passphrase: None,
activation_epoch: DEFAULT_ACTIVATION_EPOCH,
num_active_epochs: DEFAULT_NUM_ACTIVE_EPOCHS,
path: DEFAULT_KEYSTORE_PATH.to_string(),
}
}
}
Expand All @@ -60,14 +73,22 @@ impl AccountManagerConfig {
self.lifetime >= MIN_LIFETIME,
"Lifetime must be at least {MIN_LIFETIME}"
);

Ok(())
}

pub fn get_seed_phrase(&self) -> String {
if let Some(phrase) = &self.seed_phrase {
phrase.clone()
} else {
"default_seed_phrase".to_string()
// Generate a new BIP39 mnemonic with 24 words (256 bits of entropy)
let entropy: [u8; 32] = rand::random();
let mnemonic = Mnemonic::from_entropy(&entropy).expect("Failed to generate mnemonic");
let phrase = mnemonic.words().collect::<Vec<_>>().join(" ");
info!("{}", "=".repeat(89));
info!("Generated new seed phrase (KEEP SAFE): {phrase}");
info!("{}", "=".repeat(89));
phrase
}
}
}
47 changes: 41 additions & 6 deletions bin/ream/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{
env, fs,
net::SocketAddr,
path::Path,
process,
sync::Arc,
time::{Duration, SystemTime, UNIX_EPOCH},
Expand All @@ -19,6 +20,7 @@ use ream::cli::{
validator_node::ValidatorNodeConfig,
voluntary_exit::VoluntaryExitConfig,
};
use ream_account_manager::{keystore::Keystore, message_types::MessageType};
use ream_api_types_beacon::id::ValidatorID;
use ream_api_types_common::id::ID;
use ream_chain_lean::{
Expand Down Expand Up @@ -385,7 +387,7 @@ pub async fn run_validator_node(config: ValidatorNodeConfig, executor: ReamExecu
/// This function initializes the account manager by validating the configuration,
/// generating keys, and starting the account manager service.
pub async fn run_account_manager(mut config: AccountManagerConfig) {
info!("starting up account manager...");
info!("Starting account manager...");

// Validate the configuration
config
Expand All @@ -399,17 +401,50 @@ pub async fn run_account_manager(mut config: AccountManagerConfig) {

let seed_phrase = config.get_seed_phrase();

// Create keystore directory if it doesn't exist
let keystore_dir = Path::new(&config.path);
if !keystore_dir.exists() {
fs::create_dir_all(keystore_dir).expect("Failed to create keystore directory");
info!("Created keystore directory: {}", keystore_dir.display());
}

// Measure key generation time
let start_time = Instant::now();
let (_public_key, _private_key) = ream_account_manager::generate_keys(
&seed_phrase,
config.activation_epoch,
config.num_active_epochs,
);

// Generate keys sequentially for each message type
for (index, message_type) in MessageType::iter().enumerate() {
let (_public_key, _private_key) = ream_account_manager::generate_keys(
&seed_phrase,
index as u32,
config.activation_epoch,
config.num_active_epochs,
config.passphrase.as_deref().unwrap_or(""),
);

// Create keystore file using Keystore
let keystore = Keystore::from_seed_phrase(
&seed_phrase,
config.lifetime,
config.activation_epoch,
Some(format!("Ream validator keystore for {message_type}")),
Some(format!("m/44'/60'/0'/0/{index}")),
);

// Write keystore to file with enum name
let filename = message_type.to_string();
let keystore_file_path = keystore_dir.join(filename);
let keystore_json = keystore.to_json().expect("Failed to serialize keystore");

fs::write(&keystore_file_path, keystore_json).expect("Failed to write keystore file");

info!("Keystore written to path: {}", keystore_file_path.display());
}
let duration = start_time.elapsed();
info!("Key generation complete, took {:?}", duration);

info!("Account manager completed successfully");

process::exit(0);
}

/// Runs the voluntary exit process.
Expand Down
2 changes: 2 additions & 0 deletions book/cli/ream/account_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ Options:
-l, --lifetime <LIFETIME> Account lifetime in 2 ** lifetime slots [default: 18]
-c, --chunk-size <CHUNK_SIZE> Chunk size for messages [default: 5]
-s, --seed-phrase <SEED_PHRASE> Seed phrase for key generation
--passphrase <PASSPHRASE> Optional BIP39 passphrase used with the seed phrase
--activation-epoch <ACTIVATION_EPOCH> Activation epoch for the validator [default: 0]
--num-active-epochs <NUM_ACTIVE_EPOCHS> Number of active epochs [default: 262144]
--path <PATH> Path for keystore directory [default: ./.keystore/]
-h, --help Print help
```
7 changes: 7 additions & 0 deletions crates/common/account_manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ rust-version.workspace = true
version.workspace = true

[dependencies]
anyhow.workspace = true
bip39.workspace = true
chrono = { version = "0.4", features = ["serde"] }
hashsig.workspace = true
hex.workspace = true
rand.workspace = true
rand_chacha.workspace = true
serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
tracing.workspace = true
uuid = { version = "1.0", features = ["v4", "serde"] }

# ream dependencies
ream-post-quantum-crypto.workspace = true
Loading