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
10 changes: 5 additions & 5 deletions bin/genesis/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,17 +205,17 @@ mod tests {

/// Parses the generated genesis.toml, builds a genesis block, and asserts the bridge account
/// is included with nonce=1.
async fn assert_valid_genesis_block(dir: &Path) {
fn assert_valid_genesis_block(dir: &Path) {
let bridge_id = AccountFile::read(dir.join("bridge.mac")).unwrap().account.id();

let config = GenesisConfig::read_toml_file(&dir.join("genesis.toml")).unwrap();
let signer = SecretKey::read_from_bytes(&[0x01; 32]).unwrap();
let (state, _) = config.into_state(signer).unwrap();
let (state, _) = config.into_state(signer.public_key()).unwrap();

let bridge = state.accounts.iter().find(|a| a.id() == bridge_id).unwrap();
assert_eq!(bridge.nonce(), ONE);

state.into_block().await.expect("genesis block should build");
state.into_block(&signer).expect("genesis block should build");
}

#[tokio::test]
Expand All @@ -229,7 +229,7 @@ mod tests {
let ger = AccountFile::read(dir.path().join("ger_manager.mac")).unwrap();
assert_eq!(ger.auth_secret_keys.len(), 1);

assert_valid_genesis_block(dir.path()).await;
assert_valid_genesis_block(dir.path());
}

#[tokio::test]
Expand All @@ -249,6 +249,6 @@ mod tests {
let ger = AccountFile::read(dir.path().join("ger_manager.mac")).unwrap();
assert!(ger.auth_secret_keys.is_empty());

assert_valid_genesis_block(dir.path()).await;
assert_valid_genesis_block(dir.path());
}
}
47 changes: 20 additions & 27 deletions bin/node/src/commands/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use miden_node_store::genesis::config::{AccountFileWithName, GenesisConfig};
use miden_node_utils::clap::GrpcOptionsInternal;
use miden_node_utils::fs::ensure_empty_directory;
use miden_node_utils::grpc::UrlExt;
use miden_node_utils::signer::BlockSigner;
use miden_node_validator::{Validator, ValidatorSigner};
use miden_protocol::crypto::dsa::ecdsa_k256_keccak::SecretKey;
use miden_protocol::utils::serde::{Deserializable, Serializable};
Expand Down Expand Up @@ -196,42 +195,28 @@ impl ValidatorCommand {

// Bootstrap with KMS key or local key.
let signer = validator_key.into_signer().await?;
match signer {
ValidatorSigner::Kms(signer) => {
build_and_write_genesis(
config,
signer,
accounts_directory,
genesis_block_directory,
data_directory,
)
.await
},
ValidatorSigner::Local(signer) => {
build_and_write_genesis(
config,
signer,
accounts_directory,
genesis_block_directory,
data_directory,
)
.await
},
}
build_and_write_genesis(
config,
signer,
accounts_directory,
genesis_block_directory,
data_directory,
)
.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: impl BlockSigner,
signer: ValidatorSigner,
accounts_directory: &Path,
genesis_block_directory: &Path,
data_directory: &Path,
) -> anyhow::Result<()> {
// Build genesis state with the provided signer.
let (genesis_state, secrets) = config.into_state(signer)?;
let (genesis_state, secrets) = config.into_state(signer.public_key())?;

// Write account secret files.
for item in secrets.as_account_files(&genesis_state) {
Expand All @@ -247,8 +232,16 @@ async fn build_and_write_genesis(
}

// Build the signed genesis block.
let genesis_block =
genesis_state.into_block().await.context("failed to build the genesis block")?;
let unsigned_genesis_block = genesis_state
.into_unsigned_block()
.context("failed to build the unsigned genesis block")?;
let signature = signer
.sign(unsigned_genesis_block.header())
.await
.context("failed to sign the genesis block")?;
let genesis_block = unsigned_genesis_block
.into_block(signature)
.context("failed to build the genesis block")?;

// Serialize and write the genesis block to disk.
let block_bytes = genesis_block.inner().to_bytes();
Expand Down
7 changes: 3 additions & 4 deletions bin/stress-test/src/seeding/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,10 @@ pub async fn seed_store(
let asset_faucet_ids = benchmark_faucets.iter().map(Account::id).collect::<Vec<_>>();
let fee_params = FeeParameters::new(faucet.id(), 0).unwrap();
let signer = EcdsaSecretKey::new();
let genesis_state = GenesisState::new(benchmark_faucets, fee_params, 1, 1, signer.clone());
let genesis_state = GenesisState::new(benchmark_faucets, fee_params, 1, 1, signer.public_key());
let genesis_block = genesis_state
.clone()
.into_block()
.await
.into_block(&signer)
.expect("genesis block should be created");
Store::bootstrap(genesis_block, &data_directory).expect("store should bootstrap");

Expand All @@ -135,7 +134,7 @@ pub async fn seed_store(
let accounts_filepath = data_directory.join(ACCOUNTS_FILENAME);
let data_directory =
miden_node_store::DataDirectory::load(data_directory).expect("data directory should exist");
let genesis_header = genesis_state.into_block().await.unwrap().into_inner();
let genesis_header = genesis_state.into_block(&signer).unwrap().into_inner();
let metrics = generate_blocks(
num_accounts,
public_accounts_percentage,
Expand Down
6 changes: 3 additions & 3 deletions crates/block-producer/src/server/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ async fn start_store(
store_addr: std::net::SocketAddr,
data_directory: &std::path::Path,
) -> runtime::Runtime {
let genesis_state = GenesisState::new(vec![], test_fee_params(), 1, 1, random_secret_key());
let signer = random_secret_key();
let genesis_state = GenesisState::new(vec![], test_fee_params(), 1, 1, signer.public_key());
let genesis_block = genesis_state
.clone()
.into_block()
.await
.into_block(&signer)
.expect("genesis block should be created");
Store::bootstrap(genesis_block, data_directory).expect("store should bootstrap");

Expand Down
13 changes: 4 additions & 9 deletions crates/rpc/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,12 +526,12 @@ async fn start_store(store_listener: TcpListener) -> (Runtime, TempDir, Word, So

let config = GenesisConfig::default();
let signer = SecretKey::new();
let (genesis_state, _) = config.into_state(signer).unwrap();
let (genesis_state, _) = config.into_state(signer.public_key()).unwrap();
let genesis_block = genesis_state
.clone()
.into_block()
.await
.into_block(&signer)
.expect("genesis block should be created");
let genesis_commitment = genesis_block.inner().header().commitment();
Store::bootstrap(genesis_block, data_directory.path()).expect("store should bootstrap");
let dir = data_directory.path().to_path_buf();
let store_addr =
Expand Down Expand Up @@ -562,12 +562,7 @@ async fn start_store(store_listener: TcpListener) -> (Runtime, TempDir, Word, So
.await
.expect("store should start serving");
});
(
store_runtime,
data_directory,
genesis_state.into_block().await.unwrap().inner().header().commitment(),
store_addr,
)
(store_runtime, data_directory, genesis_commitment, store_addr)
}

/// Shuts down the store runtime properly to allow `RocksDB` to flush before the temp directory is
Expand Down
20 changes: 12 additions & 8 deletions crates/store/src/db/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1953,9 +1953,10 @@ async fn genesis_with_account_assets() {
.build_existing()
.unwrap();

let signer = random_secret_key();
let genesis_state =
GenesisState::new(vec![account], test_fee_params(), 1, 0, random_secret_key());
let genesis_block = genesis_state.into_block().await.unwrap();
GenesisState::new(vec![account], test_fee_params(), 1, 0, signer.public_key());
let genesis_block = genesis_state.into_block(&signer).unwrap();

crate::db::Db::bootstrap(":memory:".into(), genesis_block).unwrap();
}
Expand Down Expand Up @@ -2008,9 +2009,10 @@ async fn genesis_with_account_storage_map() {
.build_existing()
.unwrap();

let signer = random_secret_key();
let genesis_state =
GenesisState::new(vec![account], test_fee_params(), 1, 0, random_secret_key());
let genesis_block = genesis_state.into_block().await.unwrap();
GenesisState::new(vec![account], test_fee_params(), 1, 0, signer.public_key());
let genesis_block = genesis_state.into_block(&signer).unwrap();

crate::db::Db::bootstrap(":memory:".into(), genesis_block).unwrap();
}
Expand Down Expand Up @@ -2061,9 +2063,10 @@ async fn genesis_with_account_assets_and_storage() {
.build_existing()
.unwrap();

let signer = random_secret_key();
let genesis_state =
GenesisState::new(vec![account], test_fee_params(), 1, 0, random_secret_key());
let genesis_block = genesis_state.into_block().await.unwrap();
GenesisState::new(vec![account], test_fee_params(), 1, 0, signer.public_key());
let genesis_block = genesis_state.into_block(&signer).unwrap();

crate::db::Db::bootstrap(":memory:".into(), genesis_block).unwrap();
}
Expand Down Expand Up @@ -2152,14 +2155,15 @@ async fn genesis_with_multiple_accounts() {
.build_existing()
.unwrap();

let signer = random_secret_key();
let genesis_state = GenesisState::new(
vec![account1, account2, account3],
test_fee_params(),
1,
0,
random_secret_key(),
signer.public_key(),
);
let genesis_block = genesis_state.into_block().await.unwrap();
let genesis_block = genesis_state.into_block(&signer).unwrap();

crate::db::Db::bootstrap(":memory:".into(), genesis_block).unwrap();
}
Expand Down
12 changes: 6 additions & 6 deletions crates/store/src/genesis/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::str::FromStr;

use indexmap::IndexMap;
use miden_node_utils::crypto::get_rpo_random_coin;
use miden_node_utils::signer::BlockSigner;
use miden_protocol::account::auth::{AuthScheme, AuthSecretKey};
use miden_protocol::account::{
Account,
Expand All @@ -23,6 +22,7 @@ use miden_protocol::account::{
};
use miden_protocol::asset::{FungibleAsset, TokenSymbol};
use miden_protocol::block::FeeParameters;
use miden_protocol::crypto::dsa::ecdsa_k256_keccak::PublicKey;
use miden_protocol::crypto::dsa::falcon512_poseidon2::SecretKey as RpoSecretKey;
use miden_protocol::errors::TokenSymbolError;
use miden_protocol::{Felt, ONE};
Expand Down Expand Up @@ -141,10 +141,10 @@ impl GenesisConfig {
///
/// Also returns the set of secrets for the generated accounts.
#[expect(clippy::too_many_lines)]
pub fn into_state<S>(
pub fn into_state(
self,
signer: S,
) -> Result<(GenesisState<S>, AccountSecrets), GenesisConfigError> {
validator_key: PublicKey,
) -> Result<(GenesisState, AccountSecrets), GenesisConfigError> {
let GenesisConfig {
version,
timestamp,
Expand Down Expand Up @@ -335,7 +335,7 @@ impl GenesisConfig {
accounts: all_accounts,
version,
timestamp,
block_signer: signer,
validator_key,
},
AccountSecrets { secrets },
))
Expand Down Expand Up @@ -529,7 +529,7 @@ impl AccountSecrets {
/// and the index in
pub fn as_account_files(
&self,
genesis_state: &GenesisState<impl BlockSigner>,
genesis_state: &GenesisState,
) -> impl Iterator<Item = Result<AccountFileWithName, GenesisConfigError>> + '_ {
let account_lut = IndexMap::<AccountId, Account>::from_iter(
genesis_state.accounts.iter().map(|account| (account.id(), account.clone())),
Expand Down
23 changes: 14 additions & 9 deletions crates/store/src/genesis/config/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ fn parsing_yields_expected_default_values() -> TestResult {
let config_path = write_toml_file(temp_dir.path(), sample_content);

let gcfg = GenesisConfig::read_toml_file(&config_path)?;
let (state, _secrets) = gcfg.into_state(SecretKey::new())?;
let signer = SecretKey::new();
let (state, _secrets) = gcfg.into_state(signer.public_key())?;
let _ = state;
// faucets always precede wallet accounts
let native_faucet = state.accounts[0].clone();
Expand Down Expand Up @@ -70,14 +71,15 @@ fn parsing_yields_expected_default_values() -> TestResult {
#[miden_node_test_macro::enable_logging]
async fn genesis_accounts_have_nonce_one() -> TestResult {
let gcfg = GenesisConfig::default();
let (state, secrets) = gcfg.into_state(SecretKey::new()).unwrap();
let signer = SecretKey::new();
let (state, secrets) = gcfg.into_state(signer.public_key()).unwrap();
let mut iter = secrets.as_account_files(&state);
let AccountFileWithName { account_file: status_quo, .. } = iter.next().unwrap().unwrap();
assert!(iter.next().is_none());

assert_eq!(status_quo.account.nonce(), ONE);

let _block = state.into_block().await?;
let _block = state.into_block(&signer)?;
Ok(())
}

Expand Down Expand Up @@ -134,7 +136,8 @@ path = "test_account.mac"
let gcfg = GenesisConfig::read_toml_file(&config_path)?;

// Convert to state and verify the account is included
let (state, _secrets) = gcfg.into_state(SecretKey::new())?;
let signer = SecretKey::new();
let (state, _secrets) = gcfg.into_state(signer.public_key())?;
assert!(state.accounts.iter().any(|a| a.id() == account_id));

Ok(())
Expand Down Expand Up @@ -192,7 +195,8 @@ verification_base_fee = 0
let gcfg = GenesisConfig::read_toml_file(&config_path)?;

// Convert to state and verify the native faucet is included
let (state, secrets) = gcfg.into_state(SecretKey::new())?;
let signer = SecretKey::new();
let (state, secrets) = gcfg.into_state(signer.public_key())?;
assert!(state.accounts.iter().any(|a| a.id() == faucet_id));

// No secrets should be generated for file-loaded native faucet
Expand Down Expand Up @@ -251,7 +255,7 @@ verification_base_fee = 0
let gcfg = GenesisConfig::read_toml_file(&config_path)?;

// into_state should fail with NativeFaucetNotFungible error when loading the file
let result = gcfg.into_state(SecretKey::new());
let result = gcfg.into_state(SecretKey::new().public_key());
assert!(result.is_err());
let err = result.unwrap_err();
assert!(
Expand Down Expand Up @@ -284,7 +288,7 @@ path = "does_not_exist.mac"
let gcfg = GenesisConfig::read_toml_file(&config_path).unwrap();

// into_state should fail with AccountFileRead error when loading the file
let result = gcfg.into_state(SecretKey::new());
let result = gcfg.into_state(SecretKey::new().public_key());
assert!(result.is_err());
let err = result.unwrap_err();
assert!(
Expand All @@ -303,7 +307,8 @@ async fn parsing_agglayer_sample_with_account_files() -> TestResult {
.join("src/genesis/config/samples/02-with-account-files.toml");

let gcfg = GenesisConfig::read_toml_file(&sample_path)?;
let (state, secrets) = gcfg.into_state(SecretKey::new())?;
let signer = SecretKey::new();
let (state, secrets) = gcfg.into_state(signer.public_key())?;

// Should have 4 accounts:
// 1. Native faucet (MIDEN) - built from parameters
Expand Down Expand Up @@ -355,7 +360,7 @@ async fn parsing_agglayer_sample_with_account_files() -> TestResult {
assert_eq!(secrets.secrets.len(), 1, "Only native faucet should generate a secret");

// Verify the genesis state can be converted to a block
let block = state.into_block().await?;
let block = state.into_block(&signer)?;

// Verify that non-private accounts (Public and Network) get full Delta details.
for update in block.inner().body().updated_accounts() {
Expand Down
Loading
Loading