Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
137 changes: 0 additions & 137 deletions bin/validator/src/block_validation/mod.rs

This file was deleted.

33 changes: 15 additions & 18 deletions bin/validator/src/commands/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};

use anyhow::Context;
use miden_node_store::BlockStore;
use miden_node_store::genesis::config::{AccountFileWithName, GenesisConfig};
use miden_node_utils::fs::ensure_empty_directory;
use miden_protocol::utils::serde::Serializable;
use miden_validator::ValidatorSigner;
use miden_validator::{DataDirectory, ValidatorSigner};

use super::ValidatorKey;

const GENESIS_BLOCK_FILENAME: &str = "genesis.dat";

// Bootstraps the validator component.
pub async fn bootstrap(
genesis_block_directory: &Path,
Expand All @@ -34,32 +33,28 @@ pub async fn bootstrap(
}

let signer = validator_key.into_signer().await?;
build_and_write_genesis(
config,
signer,
accounts_directory,
genesis_block_directory,
data_directory,
sqlite_connection_pool_size,
let dirs = DataDirectory::load_bootstrap(
genesis_block_directory.to_path_buf(),
accounts_directory.to_path_buf(),
data_directory.to_path_buf(),
)
.await
.context("failed to load bootstrap directories")?;
build_and_write_genesis(config, signer, dirs, sqlite_connection_pool_size).await
}

/// Builds the genesis state, writes account secret files, signs the genesis block, writes it to
/// disk, and initializes the validator's database with the genesis block as the chain tip.
async fn build_and_write_genesis(
config: GenesisConfig,
signer: ValidatorSigner,
accounts_directory: &Path,
genesis_block_directory: &Path,
data_directory: &Path,
dirs: DataDirectory,
sqlite_connection_pool_size: NonZeroUsize,
) -> anyhow::Result<()> {
let (genesis_state, secrets) = config.into_state(signer.public_key())?;

for item in secrets.as_account_files(&genesis_state) {
let AccountFileWithName { account_file, name } = item?;
let account_path = accounts_directory.join(name);
let account_path = dirs.accounts_dir().expect("bootstrap directories").join(name);

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 we should restrict DataDirectory to only handle the data directory. As in, not be an enum.

Account output directory and genesis output directory are a separate matter. We could simplify these into a single --output-directory argument? Though that would be a technically breaking change right now, so maybe we punt on that, though we can prepare for it so long by making this a single struct.

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.

Can be cleaned up in a follow up PR.

// Do not override existing keys.
fs_err::OpenOptions::new()
.create_new(true)
Expand All @@ -81,12 +76,14 @@ async fn build_and_write_genesis(
.context("failed to build the genesis block")?;

let block_bytes = genesis_block.inner().to_bytes();
let genesis_block_path = genesis_block_directory.join(GENESIS_BLOCK_FILENAME);
fs_err::write(&genesis_block_path, block_bytes).context("failed to write genesis block")?;
fs_err::write(dirs.genesis_block_path().expect("bootstrap directories"), block_bytes)
.context("failed to write genesis block")?;

let _ = BlockStore::bootstrap(dirs.block_store_dir(), &genesis_block)?;

let (genesis_header, ..) = genesis_block.into_inner().into_parts();
let db = miden_validator::db::setup_with_pool_size(
data_directory.join("validator.sqlite3"),
dirs.database_path(),
sqlite_connection_pool_size,
)
.await
Expand Down
6 changes: 4 additions & 2 deletions bin/validator/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use miden_node_utils::clap::GrpcOptionsInternal;
use miden_node_utils::logging::OpenTelemetry;
use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SigningKey;
use miden_protocol::utils::serde::Deserializable;
use miden_validator::ValidatorSigner;
use miden_validator::{DataDirectory, ValidatorSigner};

const ENV_DATA_DIRECTORY: &str = "MIDEN_VALIDATOR_DATA_DIRECTORY";
const ENV_LISTEN: &str = "MIDEN_VALIDATOR_LISTEN";
Expand Down Expand Up @@ -140,7 +140,9 @@ impl ValidatorCommand {
.await
},
Self::Migrate { data_directory } => {
miden_validator::db::migrate(data_directory.join("validator.sqlite3"))
let data_dir = DataDirectory::load_server(data_directory)
.context("failed to load validator data directory")?;
miden_validator::db::migrate(data_dir.database_path())
.context("failed to apply validator database migrations")?;
Ok(())
},
Expand Down
6 changes: 4 additions & 2 deletions bin/validator/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::PathBuf;

use anyhow::Context;
use miden_node_utils::clap::GrpcOptionsInternal;
use miden_validator::{Validator, ValidatorSigner};
use miden_validator::{DataDirectory, ValidatorServer, ValidatorSigner};

// Starts the validator component.
pub async fn start(
Expand All @@ -14,7 +14,9 @@ pub async fn start(
data_directory: PathBuf,
sqlite_connection_pool_size: NonZeroUsize,
) -> anyhow::Result<()> {
Validator {
let data_directory = DataDirectory::load_server(data_directory)
.context("failed to load validator data directory")?;
ValidatorServer {
address,
grpc_options,
signer,
Expand Down
76 changes: 76 additions & 0 deletions bin/validator/src/data_directory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use std::ops::Not;
use std::path::{Path, PathBuf};

/// Represents the validator's directories and their content paths.
///
/// Used to keep our filepath assumptions in one location.
#[derive(Clone)]
pub enum DataDirectory {
/// Runtime mode: just the data directory.
Server { data: PathBuf },
/// Bootstrap mode: genesis block, accounts, and data directories.
Bootstrap {
genesis_block: PathBuf,
accounts: PathBuf,
data: PathBuf,
},
}

impl DataDirectory {
/// Loads a data directory for use by the `start` and `migrate` commands.
pub fn load_server(data: PathBuf) -> std::io::Result<Self> {
verify_is_dir(&data)?;
Ok(Self::Server { data })
}

/// Loads a data directory for use by the `bootstrap` command.
pub fn load_bootstrap(
genesis_block: PathBuf,
accounts: PathBuf,
data: PathBuf,
) -> std::io::Result<Self> {
for dir in [&genesis_block, &accounts, &data] {
verify_is_dir(dir)?;
}
Ok(Self::Bootstrap { genesis_block, accounts, data })
}

pub fn database_path(&self) -> PathBuf {
self.data().join("validator.sqlite3")
}

pub fn block_store_dir(&self) -> PathBuf {
self.data().join("blocks")
}

pub fn genesis_block_path(&self) -> Option<PathBuf> {
match self {
Self::Bootstrap { genesis_block, .. } => Some(genesis_block.join("genesis.dat")),
Self::Server { .. } => None,
}
}

pub fn accounts_dir(&self) -> Option<&Path> {
match self {
Self::Bootstrap { accounts, .. } => Some(accounts),
Self::Server { .. } => None,
}
}

pub fn display(&self) -> std::path::Display<'_> {
self.data().display()
}

fn data(&self) -> &PathBuf {
match self {
Self::Server { data } | Self::Bootstrap { data, .. } => data,
}
}
}

fn verify_is_dir(path: &PathBuf) -> std::io::Result<()> {
if fs_err::metadata(path)?.is_dir().not() {
return Err(std::io::ErrorKind::NotConnected.into());
}
Ok(())
}
5 changes: 3 additions & 2 deletions bin/validator/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
mod block_validation;
pub mod data_directory;
pub mod db;
mod server;
mod signers;
mod tx_validation;

pub use server::Validator;
pub use data_directory::DataDirectory;
pub use server::ValidatorServer;
pub use signers::{KmsSigner, ValidatorSigner};

// CONSTANTS
Expand Down
Loading
Loading