use std::path::{Path, PathBuf};
use anyhow::Context;
use miden_node_store::genesis::config::{AccountFileWithName, GenesisConfig};
use miden_node_utils::fs::ensure_empty_directory;
use miden_protocol::block::ValidatorKeys;
use miden_protocol::crypto::dsa::ecdsa_k256_keccak::PublicKey;
use miden_protocol::utils::serde::Serializable;
const GENESIS_BLOCK_FILE_NAME: &str = "genesis.dat";
pub fn generate(
genesis_block_directory: &Path,
accounts_directory: &Path,
genesis_config: Option<&PathBuf>,
validator_keys: Vec<PublicKey>,
) -> anyhow::Result<()> {
for directory in [genesis_block_directory, accounts_directory] {
ensure_empty_directory(directory)?;
}
let validator_keys =
ValidatorKeys::new(validator_keys).context("invalid genesis validator set")?;
let config = genesis_config
.map(|file_path| {
GenesisConfig::read_toml_file(file_path).with_context(|| {
format!("failed to parse genesis config from file {}", file_path.display())
})
})
.transpose()?
.unwrap_or_default();
let (genesis_state, secrets) = config.into_state(validator_keys)?;
for item in secrets.as_account_files(&genesis_state) {
let AccountFileWithName { account_file, name } = item?;
let account_path = accounts_directory.join(name);
fs_err::OpenOptions::new()
.create_new(true)
.write(true)
.open(&account_path)
.context("account file already exists")?;
account_file.write(account_path)?;
}
let native_faucet_id = genesis_state.fee_parameters.fee_faucet_id();
let genesis_block = genesis_state.into_block().context("failed to build the genesis block")?;
let genesis_block_path = genesis_block_directory.join(GENESIS_BLOCK_FILE_NAME);
fs_err::write(&genesis_block_path, genesis_block.inner().to_bytes())
.context("failed to write genesis block")?;
println!("Genesis block written to {}.", genesis_block_path.display());
println!();
println!("Native faucet account id: {}", native_faucet_id.to_hex());
println!();
println!("Seed each validator's database with:");
println!();
println!(
" miden-validator bootstrap --data-directory <DIR> --genesis {}",
genesis_block_path.display()
);
Ok(())
}