From 8e400fc4bdf56d8cc29f5957155d281e324c7ca2 Mon Sep 17 00:00:00 2001 From: Rob Walker Date: Tue, 7 May 2019 11:16:22 -0700 Subject: [PATCH] rework genesis (passive staking groundwork) (#4187) * rework genesis * fixup --- bench-exchange/src/bench.rs | 4 +- bench-tps/src/bench.rs | 6 +- core/benches/banking_stage.rs | 6 +- core/src/bank_forks.rs | 12 +- core/src/banking_stage.rs | 16 +- core/src/blockstream_service.rs | 4 +- core/src/blocktree_processor.rs | 42 ++-- core/src/broadcast_stage.rs | 4 +- core/src/fullnode.rs | 14 +- core/src/genesis_utils.rs | 51 +++++ core/src/leader_schedule_cache.rs | 15 +- core/src/leader_schedule_utils.rs | 11 +- core/src/lib.rs | 1 + core/src/local_cluster.rs | 6 +- core/src/poh_recorder.rs | 28 +-- core/src/poh_service.rs | 4 +- core/src/replay_stage.rs | 6 +- core/src/rpc.rs | 4 +- core/src/rpc_pubsub.rs | 12 +- core/src/rpc_service.rs | 4 +- core/src/rpc_subscriptions.rs | 8 +- core/src/staking_utils.rs | 22 +- core/src/storage_stage.rs | 8 +- core/src/tvu.rs | 4 +- core/src/window_service.rs | 8 +- core/tests/replicator.rs | 4 +- core/tests/tvu.rs | 18 +- genesis/Cargo.toml | 2 +- genesis/src/main.rs | 136 +++++++----- ledger-tool/tests/basic.rs | 7 +- programs/bpf/tests/programs.rs | 8 +- programs/budget_api/src/budget_processor.rs | 4 +- programs/config_api/src/config_processor.rs | 4 +- .../exchange_api/src/exchange_processor.rs | 4 +- programs/failure_program/tests/failure.rs | 4 +- programs/noop_program/tests/noop.rs | 4 +- programs/storage_api/src/storage_processor.rs | 6 +- programs/vote_api/src/vote_state.rs | 15 ++ runtime/benches/accounts.rs | 6 +- runtime/benches/bank.rs | 4 +- runtime/src/bank.rs | 202 ++++++++---------- runtime/src/bank_client.rs | 4 +- runtime/src/system_instruction_processor.rs | 4 +- sdk/src/genesis_block.rs | 133 +++++++----- 44 files changed, 475 insertions(+), 394 deletions(-) create mode 100644 core/src/genesis_utils.rs diff --git a/bench-exchange/src/bench.rs b/bench-exchange/src/bench.rs index 596b65aac5..4b8f6a4f5e 100644 --- a/bench-exchange/src/bench.rs +++ b/bench-exchange/src/bench.rs @@ -913,7 +913,7 @@ mod tests { use solana_exchange_api::exchange_processor::process_instruction; use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use std::sync::mpsc::channel; #[test] @@ -990,7 +990,7 @@ mod tests { #[test] fn test_exchange_bank_client() { solana_logger::setup(); - let (genesis_block, identity) = GenesisBlock::new(100_000_000_000_000); + let (genesis_block, identity) = create_genesis_block(100_000_000_000_000); let mut bank = Bank::new(&genesis_block); bank.add_instruction_processor(id(), process_instruction); let clients = vec![BankClient::new(bank)]; diff --git a/bench-tps/src/bench.rs b/bench-tps/src/bench.rs index a224511c12..589a2815b7 100644 --- a/bench-tps/src/bench.rs +++ b/bench-tps/src/bench.rs @@ -640,7 +640,7 @@ mod tests { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use std::sync::mpsc::channel; #[test] @@ -701,7 +701,7 @@ mod tests { #[test] fn test_bench_tps_bank_client() { - let (genesis_block, id) = GenesisBlock::new(10_000); + let (genesis_block, id) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let clients = vec![BankClient::new(bank)]; @@ -718,7 +718,7 @@ mod tests { #[test] fn test_bench_tps_fund_keys() { - let (genesis_block, id) = GenesisBlock::new(10_000); + let (genesis_block, id) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let client = BankClient::new(bank); let tx_count = 10; diff --git a/core/benches/banking_stage.rs b/core/benches/banking_stage.rs index 01b199a510..cfbbaf93ba 100644 --- a/core/benches/banking_stage.rs +++ b/core/benches/banking_stage.rs @@ -10,11 +10,11 @@ use solana::banking_stage::{create_test_recorder, BankingStage}; use solana::blocktree::{get_tmp_ledger_path, Blocktree}; use solana::cluster_info::ClusterInfo; use solana::cluster_info::Node; +use solana::genesis_utils::create_genesis_block; use solana::packet::to_packets_chunked; use solana::poh_recorder::WorkingBankEntries; use solana::service::Service; use solana_runtime::bank::Bank; -use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::hash; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{KeypairUtil, Signature}; @@ -52,7 +52,7 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { // a multiple of packet chunk 2X duplicates to avoid races let txes = 192 * 50 * num_threads * 2; let mint_total = 1_000_000_000_000; - let (genesis_block, mint_keypair) = GenesisBlock::new(mint_total); + let (genesis_block, mint_keypair) = create_genesis_block(mint_total); let (verified_sender, verified_receiver) = channel(); let (vote_sender, vote_receiver) = channel(); @@ -159,7 +159,7 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { // a multiple of packet chunk 2X duplicates to avoid races let txes = 96 * 100 * num_threads * 2; let mint_total = 1_000_000_000_000; - let (genesis_block, mint_keypair) = GenesisBlock::new(mint_total); + let (genesis_block, mint_keypair) = create_genesis_block(mint_total); let (verified_sender, verified_receiver) = channel(); let (vote_sender, vote_receiver) = channel(); diff --git a/core/src/bank_forks.rs b/core/src/bank_forks.rs index 6a1114d92a..a0fe909b81 100644 --- a/core/src/bank_forks.rs +++ b/core/src/bank_forks.rs @@ -128,13 +128,13 @@ impl BankForks { #[cfg(test)] mod tests { use super::*; - use solana_sdk::genesis_block::GenesisBlock; + use crate::genesis_utils::create_genesis_block; use solana_sdk::hash::Hash; use solana_sdk::pubkey::Pubkey; #[test] fn test_bank_forks() { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let mut bank_forks = BankForks::new(0, bank); let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1); @@ -146,7 +146,7 @@ mod tests { #[test] fn test_bank_forks_descendants() { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let mut bank_forks = BankForks::new(0, bank); let bank0 = bank_forks[0].clone(); @@ -163,7 +163,7 @@ mod tests { #[test] fn test_bank_forks_ancestors() { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let mut bank_forks = BankForks::new(0, bank); let bank0 = bank_forks[0].clone(); @@ -181,7 +181,7 @@ mod tests { #[test] fn test_bank_forks_frozen_banks() { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let mut bank_forks = BankForks::new(0, bank); let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1); @@ -192,7 +192,7 @@ mod tests { #[test] fn test_bank_forks_active_banks() { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let mut bank_forks = BankForks::new(0, bank); let child_bank = Bank::new_from_parent(&bank_forks[0u64], &Pubkey::default(), 1); diff --git a/core/src/banking_stage.rs b/core/src/banking_stage.rs index f6bbddc87c..0e1392ff07 100644 --- a/core/src/banking_stage.rs +++ b/core/src/banking_stage.rs @@ -674,10 +674,10 @@ mod tests { use crate::blocktree::get_tmp_ledger_path; use crate::cluster_info::Node; use crate::entry::EntrySlice; + use crate::genesis_utils::create_genesis_block; use crate::packet::to_packets; use crate::poh_recorder::WorkingBank; use crate::{get_tmp_ledger_path, tmp_ledger_name}; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::instruction::InstructionError; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction; @@ -687,7 +687,7 @@ mod tests { #[test] fn test_banking_stage_shutdown1() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let genesis_block = create_genesis_block(2).0; let bank = Arc::new(Bank::new(&genesis_block)); let (verified_sender, verified_receiver) = channel(); let (vote_sender, vote_receiver) = channel(); @@ -718,7 +718,7 @@ mod tests { #[test] fn test_banking_stage_tick() { solana_logger::setup(); - let (mut genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (mut genesis_block, _mint_keypair) = create_genesis_block(2); genesis_block.ticks_per_slot = 4; let bank = Arc::new(Bank::new(&genesis_block)); let start_hash = bank.last_blockhash(); @@ -764,7 +764,7 @@ mod tests { #[test] fn test_banking_stage_entries_only() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(10); + let (genesis_block, mint_keypair) = create_genesis_block(10); let bank = Arc::new(Bank::new(&genesis_block)); let start_hash = bank.last_blockhash(); let (verified_sender, verified_receiver) = channel(); @@ -867,7 +867,7 @@ mod tests { // In this attack we'll demonstrate that a verifier can interpret the ledger // differently if either the server doesn't signal the ledger to add an // Entry OR if the verifier tries to parallelize across multiple Entries. - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let (verified_sender, verified_receiver) = channel(); // Process a batch that includes a transaction that receives two lamports. @@ -956,7 +956,7 @@ mod tests { #[test] fn test_bank_record_transactions() { - let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, mint_keypair) = create_genesis_block(10_000); let bank = Arc::new(Bank::new(&genesis_block)); let working_bank = WorkingBank { bank: bank.clone(), @@ -1015,7 +1015,7 @@ mod tests { #[test] fn test_bank_process_received_transactions() { - let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, mint_keypair) = create_genesis_block(10_000); let bank = Arc::new(Bank::new(&genesis_block)); let ledger_path = get_tmp_ledger_path!(); { @@ -1171,7 +1171,7 @@ mod tests { #[test] fn test_bank_process_and_record_transactions() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, mint_keypair) = create_genesis_block(10_000); let bank = Arc::new(Bank::new(&genesis_block)); let pubkey = Pubkey::new_rand(); diff --git a/core/src/blockstream_service.rs b/core/src/blockstream_service.rs index e673df668c..d60fe2e63c 100644 --- a/core/src/blockstream_service.rs +++ b/core/src/blockstream_service.rs @@ -109,10 +109,10 @@ mod test { use super::*; use crate::blocktree::create_new_tmp_ledger; use crate::entry::{create_ticks, Entry}; + use crate::genesis_utils::create_genesis_block; use bincode::{deserialize, serialize}; use chrono::{DateTime, FixedOffset}; use serde_json::Value; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction; @@ -124,7 +124,7 @@ mod test { let leader_id = Pubkey::new_rand(); // Set up genesis block and blocktree - let (mut genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let (mut genesis_block, _mint_keypair) = create_genesis_block(1000); genesis_block.ticks_per_slot = ticks_per_slot; let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); diff --git a/core/src/blocktree_processor.rs b/core/src/blocktree_processor.rs index 75ea09eebf..dc00e0c9d7 100644 --- a/core/src/blocktree_processor.rs +++ b/core/src/blocktree_processor.rs @@ -264,7 +264,7 @@ mod tests { use crate::blocktree::create_new_tmp_ledger; use crate::blocktree::tests::entries_to_blobs; use crate::entry::{create_ticks, next_entry, next_entry_mut, Entry}; - use solana_sdk::genesis_block::GenesisBlock; + use crate::genesis_utils::{create_genesis_block, create_genesis_block_with_leader}; use solana_sdk::hash::Hash; use solana_sdk::instruction::InstructionError; use solana_sdk::pubkey::Pubkey; @@ -292,7 +292,7 @@ mod tests { fn test_process_blocktree_with_incomplete_slot() { solana_logger::setup(); - let (genesis_block, _mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, _mint_keypair) = create_genesis_block(10_000); let ticks_per_slot = genesis_block.ticks_per_slot; /* @@ -349,7 +349,7 @@ mod tests { fn test_process_blocktree_with_two_forks_and_squash() { solana_logger::setup(); - let (genesis_block, _mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, _mint_keypair) = create_genesis_block(10_000); let ticks_per_slot = genesis_block.ticks_per_slot; // Create a new ledger with slot 0 full of ticks @@ -421,7 +421,7 @@ mod tests { fn test_process_blocktree_with_two_forks() { solana_logger::setup(); - let (genesis_block, _mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, _mint_keypair) = create_genesis_block(10_000); let ticks_per_slot = genesis_block.ticks_per_slot; // Create a new ledger with slot 0 full of ticks @@ -543,7 +543,7 @@ mod tests { fn test_process_empty_entry_is_registered() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); let slot_entries = create_ticks(genesis_block.ticks_per_slot - 1, genesis_block.hash()); @@ -570,13 +570,16 @@ mod tests { fn test_process_ledger_simple() { solana_logger::setup(); let leader_pubkey = Pubkey::new_rand(); - let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(100, &leader_pubkey, 50); + let mint = 100; + let (genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(mint, &leader_pubkey, 50); let (ledger_path, mut last_entry_hash) = create_new_tmp_ledger!(&genesis_block); debug!("ledger_path: {:?}", ledger_path); + let deducted_from_mint = 3; let mut entries = vec![]; let blockhash = genesis_block.hash(); - for _ in 0..3 { + for _ in 0..deducted_from_mint { // Transfer one token from the mint to a random account let keypair = Keypair::new(); let tx = system_transaction::create_user_account( @@ -627,14 +630,17 @@ mod tests { ); let bank = bank_forks[1].clone(); - assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 50 - 3); + assert_eq!( + bank.get_balance(&mint_keypair.pubkey()), + mint - deducted_from_mint + ); assert_eq!(bank.tick_height(), 2 * genesis_block.ticks_per_slot - 1); assert_eq!(bank.last_blockhash(), entries.last().unwrap().hash); } #[test] fn test_process_ledger_with_one_tick_per_slot() { - let (mut genesis_block, _mint_keypair) = GenesisBlock::new(123); + let (mut genesis_block, _mint_keypair) = create_genesis_block(123); genesis_block.ticks_per_slot = 1; let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); @@ -656,7 +662,7 @@ mod tests { #[test] fn test_process_entries_tick() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, _mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); // ensure bank can process a tick @@ -668,7 +674,7 @@ mod tests { #[test] fn test_process_entries_2_entries_collision() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -700,7 +706,7 @@ mod tests { #[test] fn test_process_entries_2_txes_collision() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -756,7 +762,7 @@ mod tests { #[test] fn test_process_entries_2_txes_collision_and_error() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -838,7 +844,7 @@ mod tests { #[test] fn test_process_entries_2_entries_par() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -889,7 +895,7 @@ mod tests { #[test] fn test_process_entries_2_entries_tick() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -957,7 +963,7 @@ mod tests { #[test] fn test_update_transaction_statuses() { // Make sure instruction errors still update the signature cache - let (genesis_block, mint_keypair) = GenesisBlock::new(11_000); + let (genesis_block, mint_keypair) = create_genesis_block(11_000); let bank = Bank::new(&genesis_block); let pubkey = Pubkey::new_rand(); bank.transfer(1_000, &mint_keypair, &pubkey).unwrap(); @@ -1000,7 +1006,7 @@ mod tests { #[test] fn test_update_transaction_statuses_fail() { - let (genesis_block, mint_keypair) = GenesisBlock::new(11_000); + let (genesis_block, mint_keypair) = create_genesis_block(11_000); let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); @@ -1043,7 +1049,7 @@ mod tests { // this test throws lots of rayon threads at process_entries() // finds bugs in very low-layer stuff solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(1_000_000_000); + let (genesis_block, mint_keypair) = create_genesis_block(1_000_000_000); let mut bank = Bank::new(&genesis_block); const NUM_TRANSFERS: usize = 100; diff --git a/core/src/broadcast_stage.rs b/core/src/broadcast_stage.rs index d46ef69ca5..d9cc66b610 100644 --- a/core/src/broadcast_stage.rs +++ b/core/src/broadcast_stage.rs @@ -271,9 +271,9 @@ mod test { use crate::blocktree::{get_tmp_ledger_path, Blocktree}; use crate::cluster_info::{ClusterInfo, Node}; use crate::entry::create_ticks; + use crate::genesis_utils::create_genesis_block; use crate::service::Service; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::sync::atomic::AtomicBool; @@ -310,7 +310,7 @@ mod test { let exit_sender = Arc::new(AtomicBool::new(false)); - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank = Arc::new(Bank::new(&genesis_block)); // Start up the broadcast stage diff --git a/core/src/fullnode.rs b/core/src/fullnode.rs index bd91c4f189..687090058b 100644 --- a/core/src/fullnode.rs +++ b/core/src/fullnode.rs @@ -389,13 +389,14 @@ pub fn make_active_set_entries( pub fn new_fullnode_for_tests() -> (Fullnode, ContactInfo, Keypair, String) { use crate::blocktree::create_new_tmp_ledger; + use crate::genesis_utils::create_genesis_block_with_leader; let node_keypair = Arc::new(Keypair::new()); let node = Node::new_localhost_with_pubkey(&node_keypair.pubkey()); let contact_info = node.info.clone(); - let (mut genesis_block, mint_keypair) = - GenesisBlock::new_with_leader(10_000, &contact_info.id, 42); + let (mut genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(10_000, &contact_info.id, 42); genesis_block .native_instruction_processors .push(("solana_budget_program".to_string(), solana_budget_api::id())); @@ -420,6 +421,7 @@ pub fn new_fullnode_for_tests() -> (Fullnode, ContactInfo, Keypair, String) { mod tests { use super::*; use crate::blocktree::create_new_tmp_ledger; + use crate::genesis_utils::create_genesis_block_with_leader; use std::fs::remove_dir_all; #[test] @@ -429,8 +431,8 @@ mod tests { let validator_keypair = Keypair::new(); let validator_node = Node::new_localhost_with_pubkey(&validator_keypair.pubkey()); - let (genesis_block, _mint_keypair) = - GenesisBlock::new_with_leader(10_000, &leader_keypair.pubkey(), 1000); + let genesis_block = + create_genesis_block_with_leader(10_000, &leader_keypair.pubkey(), 1000).0; let (validator_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); let voting_keypair = Keypair::new(); @@ -457,8 +459,8 @@ mod tests { .map(|_| { let validator_keypair = Keypair::new(); let validator_node = Node::new_localhost_with_pubkey(&validator_keypair.pubkey()); - let (genesis_block, _mint_keypair) = - GenesisBlock::new_with_leader(10_000, &leader_keypair.pubkey(), 1000); + let (genesis_block, _mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(10_000, &leader_keypair.pubkey(), 1000); let (validator_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); ledger_paths.push(validator_ledger_path.clone()); let voting_keypair = Keypair::new(); diff --git a/core/src/genesis_utils.rs b/core/src/genesis_utils.rs new file mode 100644 index 0000000000..ee6f4ea77a --- /dev/null +++ b/core/src/genesis_utils.rs @@ -0,0 +1,51 @@ +use solana_sdk::account::Account; +use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::pubkey::Pubkey; +use solana_sdk::signature::{Keypair, KeypairUtil}; +use solana_sdk::system_program; +use solana_vote_api::vote_state; + +// The default stake placed with the bootstrap leader +pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 42; + +pub fn create_genesis_block_with_leader( + mint_lamports: u64, + leader_id: &Pubkey, + leader_stake_lamports: u64, +) -> (GenesisBlock, Keypair, Keypair) { + let mint_keypair = Keypair::new(); + let voting_keypair = Keypair::new(); + + let genesis_block = GenesisBlock::new( + &leader_id, + &[ + ( + mint_keypair.pubkey(), + Account::new(mint_lamports, 0, &system_program::id()), + ), + ( + voting_keypair.pubkey(), + vote_state::create_bootstrap_leader_account( + &voting_keypair.pubkey(), + &leader_id, + 0, + leader_stake_lamports, + ), + ), + ], + &[], + ); + + (genesis_block, mint_keypair, voting_keypair) +} + +// same as genesis_block::create_genesis_block, but with leader staking logic specific +// to this crate +pub fn create_genesis_block(mint_lamports: u64) -> (GenesisBlock, Keypair) { + let (genesis_block, mint_keypair, _vote_keypair) = create_genesis_block_with_leader( + mint_lamports, + &Pubkey::new_rand(), + BOOTSTRAP_LEADER_LAMPORTS, + ); + (genesis_block, mint_keypair) +} diff --git a/core/src/leader_schedule_cache.rs b/core/src/leader_schedule_cache.rs index 569a0d42bf..c234e9e811 100644 --- a/core/src/leader_schedule_cache.rs +++ b/core/src/leader_schedule_cache.rs @@ -165,9 +165,10 @@ impl LeaderScheduleCache { mod tests { use super::*; use crate::blocktree::tests::make_slot_entries; + use crate::genesis_utils::create_genesis_block; + use crate::genesis_utils::{create_genesis_block_with_leader, BOOTSTRAP_LEADER_LAMPORTS}; use crate::voting_keypair::tests::new_vote_account; use solana_runtime::bank::{Bank, EpochSchedule, MINIMUM_SLOT_LENGTH}; - use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS}; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::sync::mpsc::channel; use std::sync::Arc; @@ -177,7 +178,7 @@ mod tests { #[test] fn test_slot_leader_at() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Bank::new(&genesis_block); let cache = LeaderScheduleCache::new_from_bank(&bank); @@ -219,7 +220,7 @@ mod tests { fn run_thread_race() { let slots_per_epoch = MINIMUM_SLOT_LENGTH as u64; let epoch_schedule = EpochSchedule::new(slots_per_epoch, slots_per_epoch / 2, true); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let cache = Arc::new(LeaderScheduleCache::new(epoch_schedule, bank.slot())); @@ -258,7 +259,7 @@ mod tests { #[test] fn test_next_leader_slot() { let pubkey = Pubkey::new_rand(); - let mut genesis_block = GenesisBlock::new_with_leader( + let mut genesis_block = create_genesis_block_with_leader( BOOTSTRAP_LEADER_LAMPORTS, &pubkey, BOOTSTRAP_LEADER_LAMPORTS, @@ -299,7 +300,7 @@ mod tests { #[test] fn test_next_leader_slot_blocktree() { let pubkey = Pubkey::new_rand(); - let mut genesis_block = GenesisBlock::new_with_leader( + let mut genesis_block = create_genesis_block_with_leader( BOOTSTRAP_LEADER_LAMPORTS, &pubkey, BOOTSTRAP_LEADER_LAMPORTS, @@ -371,7 +372,7 @@ mod tests { #[test] fn test_next_leader_slot_next_epoch() { let pubkey = Pubkey::new_rand(); - let (mut genesis_block, mint_keypair) = GenesisBlock::new_with_leader( + let (mut genesis_block, mint_keypair, _voting_keypair) = create_genesis_block_with_leader( 2 * BOOTSTRAP_LEADER_LAMPORTS, &pubkey, BOOTSTRAP_LEADER_LAMPORTS, @@ -423,7 +424,7 @@ mod tests { #[test] fn test_schedule_for_unconfirmed_epoch() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let cache = LeaderScheduleCache::new_from_bank(&bank); diff --git a/core/src/leader_schedule_utils.rs b/core/src/leader_schedule_utils.rs index 1c0bf90eb4..0540cd1dda 100644 --- a/core/src/leader_schedule_utils.rs +++ b/core/src/leader_schedule_utils.rs @@ -56,17 +56,14 @@ fn sort_stakes(stakes: &mut Vec<(Pubkey, u64)>) { #[cfg(test)] mod tests { use super::*; + use crate::genesis_utils::{create_genesis_block_with_leader, BOOTSTRAP_LEADER_LAMPORTS}; use crate::staking_utils; - use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS}; #[test] fn test_leader_schedule_via_bank() { let pubkey = Pubkey::new_rand(); - let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader( - BOOTSTRAP_LEADER_LAMPORTS, - &pubkey, - BOOTSTRAP_LEADER_LAMPORTS, - ); + let genesis_block = + create_genesis_block_with_leader(0, &pubkey, BOOTSTRAP_LEADER_LAMPORTS).0; let bank = Bank::new(&genesis_block); let ids_and_stakes: Vec<_> = staking_utils::delegated_stakes(&bank).into_iter().collect(); @@ -86,7 +83,7 @@ mod tests { #[test] fn test_leader_scheduler1_basic() { let pubkey = Pubkey::new_rand(); - let genesis_block = GenesisBlock::new_with_leader( + let genesis_block = create_genesis_block_with_leader( BOOTSTRAP_LEADER_LAMPORTS, &pubkey, BOOTSTRAP_LEADER_LAMPORTS, diff --git a/core/src/lib.rs b/core/src/lib.rs index 6a58b3340f..2d103053eb 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -35,6 +35,7 @@ pub mod erasure; pub mod fetch_stage; pub mod fullnode; pub mod gen_keys; +pub mod genesis_utils; pub mod gossip_service; pub mod leader_schedule; pub mod leader_schedule_cache; diff --git a/core/src/local_cluster.rs b/core/src/local_cluster.rs index 3a14c131f5..6161aa8464 100644 --- a/core/src/local_cluster.rs +++ b/core/src/local_cluster.rs @@ -3,6 +3,7 @@ use crate::cluster::Cluster; use crate::cluster_info::{Node, FULLNODE_PORT_RANGE}; use crate::contact_info::ContactInfo; use crate::fullnode::{Fullnode, FullnodeConfig}; +use crate::genesis_utils::create_genesis_block_with_leader; use crate::gossip_service::discover_nodes; use crate::replicator::Replicator; use crate::service::Service; @@ -115,11 +116,10 @@ impl LocalCluster { } pub fn new(config: &ClusterConfig) -> Self { - let voting_keypair = Keypair::new(); let leader_keypair = Arc::new(Keypair::new()); let leader_pubkey = leader_keypair.pubkey(); let leader_node = Node::new_localhost_with_pubkey(&leader_keypair.pubkey()); - let (mut genesis_block, mint_keypair) = GenesisBlock::new_with_leader( + let (mut genesis_block, mint_keypair, voting_keypair) = create_genesis_block_with_leader( config.cluster_lamports, &leader_pubkey, config.node_stakes[0], @@ -129,7 +129,7 @@ impl LocalCluster { genesis_block .native_instruction_processors .extend_from_slice(&config.native_instruction_processors); - genesis_block.bootstrap_leader_vote_account_id = voting_keypair.pubkey(); + let (genesis_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); let leader_ledger_path = tmp_copy_blocktree!(&genesis_ledger_path); let leader_contact_info = leader_node.info.clone(); diff --git a/core/src/poh_recorder.rs b/core/src/poh_recorder.rs index 2ae7350c9f..9a326dbd91 100644 --- a/core/src/poh_recorder.rs +++ b/core/src/poh_recorder.rs @@ -404,9 +404,9 @@ impl PohRecorder { mod tests { use super::*; use crate::blocktree::{get_tmp_ledger_path, Blocktree}; + use crate::genesis_utils::create_genesis_block; use crate::leader_schedule_cache::LeaderScheduleCache; use crate::test_tx::test_tx; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::hash; use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT; use std::sync::mpsc::sync_channel; @@ -495,7 +495,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, _entry_receiver) = PohRecorder::new( @@ -528,7 +528,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -573,7 +573,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -616,7 +616,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -653,7 +653,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, _entry_receiver) = PohRecorder::new( @@ -692,7 +692,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -738,7 +738,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -781,7 +781,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, entry_receiver) = PohRecorder::new( @@ -909,7 +909,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let (mut poh_recorder, _entry_receiver) = PohRecorder::new( 0, @@ -940,7 +940,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let (sender, receiver) = sync_channel(1); let (mut poh_recorder, _entry_receiver) = PohRecorder::new_with_clear_signal( @@ -968,7 +968,7 @@ mod tests { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); let ticks_per_slot = 5; - let (mut genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (mut genesis_block, _mint_keypair) = create_genesis_block(2); genesis_block.ticks_per_slot = ticks_per_slot; let bank = Arc::new(Bank::new(&genesis_block)); @@ -1015,7 +1015,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, _entry_receiver) = PohRecorder::new( @@ -1176,7 +1176,7 @@ mod tests { { let blocktree = Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"); - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let (mut poh_recorder, _entry_receiver) = PohRecorder::new( diff --git a/core/src/poh_service.rs b/core/src/poh_service.rs index 180739c568..de63818a0d 100644 --- a/core/src/poh_service.rs +++ b/core/src/poh_service.rs @@ -107,18 +107,18 @@ impl Service for PohService { mod tests { use super::*; use crate::blocktree::{get_tmp_ledger_path, Blocktree}; + use crate::genesis_utils::create_genesis_block; use crate::leader_schedule_cache::LeaderScheduleCache; use crate::poh_recorder::WorkingBank; use crate::result::Result; use crate::test_tx::test_tx; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::hash; use solana_sdk::pubkey::Pubkey; #[test] fn test_poh_service() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let (genesis_block, _mint_keypair) = create_genesis_block(2); let bank = Arc::new(Bank::new(&genesis_block)); let prev_hash = bank.last_blockhash(); let ledger_path = get_tmp_ledger_path!(); diff --git a/core/src/replay_stage.rs b/core/src/replay_stage.rs index 8bbb8d0401..ed9c963ba0 100644 --- a/core/src/replay_stage.rs +++ b/core/src/replay_stage.rs @@ -608,9 +608,9 @@ impl Service for ReplayStage { mod test { use super::*; use crate::blocktree::get_tmp_ledger_path; + use crate::genesis_utils::create_genesis_block; use crate::packet::Blob; use crate::replay_stage::ReplayStage; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::Hash; use std::fs::remove_dir_all; use std::sync::{Arc, RwLock}; @@ -623,7 +623,7 @@ mod test { Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"), ); - let genesis_block = GenesisBlock::new(10_000).0; + let genesis_block = create_genesis_block(10_000).0; let bank0 = Bank::new(&genesis_block); let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank0)); let mut bank_forks = BankForks::new(0, bank0); @@ -662,7 +662,7 @@ mod test { #[test] fn test_handle_new_root() { - let genesis_block = GenesisBlock::new(10_000).0; + let genesis_block = create_genesis_block(10_000).0; let bank0 = Bank::new(&genesis_block); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank0))); let mut progress = HashMap::new(); diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 9be9988a5b..1b17d93503 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -478,8 +478,8 @@ impl RpcSol for RpcSolImpl { mod tests { use super::*; use crate::contact_info::ContactInfo; + use crate::genesis_utils::create_genesis_block; use jsonrpc_core::{MetaIoHandler, Response}; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::{hash, Hash}; use solana_sdk::instruction::InstructionError; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -832,7 +832,7 @@ mod tests { } fn new_bank_forks() -> (Arc>, Keypair) { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); ( Arc::new(RwLock::new(BankForks::new(bank.slot(), bank))), diff --git a/core/src/rpc_pubsub.rs b/core/src/rpc_pubsub.rs index ef16b9d149..6e449b16fd 100644 --- a/core/src/rpc_pubsub.rs +++ b/core/src/rpc_pubsub.rs @@ -250,13 +250,13 @@ impl RpcSolPubSub for RpcSolPubSubImpl { mod tests { use super::*; use crate::bank_forks::BankForks; + use crate::genesis_utils::create_genesis_block; use jsonrpc_core::futures::sync::mpsc; use jsonrpc_core::Response; use jsonrpc_pubsub::{PubSubHandler, Session}; use solana_budget_api; use solana_budget_api::budget_instruction; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_program; @@ -288,7 +288,7 @@ mod tests { #[test] fn test_signature_subscribe() { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let bob = Keypair::new(); let bob_pubkey = bob.pubkey(); let bank = Bank::new(&genesis_block); @@ -321,7 +321,7 @@ mod tests { #[test] fn test_signature_unsubscribe() { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let bob_pubkey = Pubkey::new_rand(); let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); @@ -363,7 +363,7 @@ mod tests { #[test] fn test_account_subscribe() { - let (mut genesis_block, alice) = GenesisBlock::new(10_000); + let (mut genesis_block, alice) = create_genesis_block(10_000); // This test depends on the budget program genesis_block @@ -503,7 +503,7 @@ mod tests { #[test] #[should_panic] fn test_account_confirmations_not_fulfilled() { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank))); @@ -528,7 +528,7 @@ mod tests { #[test] fn test_account_confirmations() { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank))); diff --git a/core/src/rpc_service.rs b/core/src/rpc_service.rs index a514fd9f3e..b36ca6a643 100644 --- a/core/src/rpc_service.rs +++ b/core/src/rpc_service.rs @@ -88,14 +88,14 @@ impl Service for JsonRpcService { mod tests { use super::*; use crate::contact_info::ContactInfo; + use crate::genesis_utils::create_genesis_block; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::signature::KeypairUtil; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; #[test] fn test_rpc_new() { - let (genesis_block, alice) = GenesisBlock::new(10_000); + let (genesis_block, alice) = create_genesis_block(10_000); let exit = Arc::new(AtomicBool::new(false)); let bank = Bank::new(&genesis_block); let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_invalid_keypair( diff --git a/core/src/rpc_subscriptions.rs b/core/src/rpc_subscriptions.rs index 9c9b5709fa..9b04ca47f9 100644 --- a/core/src/rpc_subscriptions.rs +++ b/core/src/rpc_subscriptions.rs @@ -299,16 +299,16 @@ impl RpcSubscriptions { #[cfg(test)] mod tests { use super::*; + use crate::genesis_utils::create_genesis_block; use jsonrpc_pubsub::typed::Subscriber; use solana_budget_api; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction; use tokio::prelude::{Async, Stream}; #[test] fn test_check_account_subscribe() { - let (genesis_block, mint_keypair) = GenesisBlock::new(100); + let (genesis_block, mint_keypair) = create_genesis_block(100); let bank = Bank::new(&genesis_block); let blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank))); @@ -360,7 +360,7 @@ mod tests { #[test] fn test_check_program_subscribe() { - let (genesis_block, mint_keypair) = GenesisBlock::new(100); + let (genesis_block, mint_keypair) = create_genesis_block(100); let bank = Bank::new(&genesis_block); let blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank))); @@ -411,7 +411,7 @@ mod tests { } #[test] fn test_check_signature_subscribe() { - let (genesis_block, mint_keypair) = GenesisBlock::new(100); + let (genesis_block, mint_keypair) = create_genesis_block(100); let bank = Bank::new(&genesis_block); let blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(0, bank))); diff --git a/core/src/staking_utils.rs b/core/src/staking_utils.rs index 77e1055411..17416c396c 100644 --- a/core/src/staking_utils.rs +++ b/core/src/staking_utils.rs @@ -146,11 +146,13 @@ where } #[cfg(test)] -mod tests { +pub mod tests { use super::*; + use crate::genesis_utils::{ + create_genesis_block, create_genesis_block_with_leader, BOOTSTRAP_LEADER_LAMPORTS, + }; use crate::voting_keypair::tests as voting_keypair_tests; use hashbrown::HashSet; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::iter::FromIterator; @@ -162,10 +164,9 @@ mod tests { #[test] fn test_bank_staked_nodes_at_epoch() { - let pubkey = Pubkey::new_rand(); - let bootstrap_lamports = 2; - let (genesis_block, _) = - GenesisBlock::new_with_leader(bootstrap_lamports, &pubkey, bootstrap_lamports); + let (genesis_block, _mint_keypair, voting_keypair) = + create_genesis_block_with_leader(1, &Pubkey::new_rand(), BOOTSTRAP_LEADER_LAMPORTS); + let bank = Bank::new(&genesis_block); // Epoch doesn't exist @@ -173,7 +174,7 @@ mod tests { assert_eq!(vote_account_balances_at_epoch(&bank, 10), None); // First epoch has the bootstrap leader - expected.insert(genesis_block.bootstrap_leader_vote_account_id, 1); + expected.insert(voting_keypair.pubkey(), BOOTSTRAP_LEADER_LAMPORTS); let expected = Some(expected); assert_eq!(vote_account_balances_at_epoch(&bank, 0), expected); @@ -187,7 +188,7 @@ mod tests { fn test_epoch_stakes_and_lockouts() { let validator = Keypair::new(); - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let bank = Bank::new(&genesis_block); let bank_voter = Keypair::new(); @@ -221,10 +222,11 @@ mod tests { let bank = new_from_parent(&Arc::new(bank), slot); let result: Vec<_> = epoch_stakes_and_lockouts(&bank, 0); - assert_eq!(result, vec![(1, None)]); + assert_eq!(result, vec![(BOOTSTRAP_LEADER_LAMPORTS, None)]); let result: HashSet<_> = HashSet::from_iter(epoch_stakes_and_lockouts(&bank, epoch)); - let expected: HashSet<_> = HashSet::from_iter(vec![(1, None), (499, None)]); + let expected: HashSet<_> = + HashSet::from_iter(vec![(BOOTSTRAP_LEADER_LAMPORTS, None), (499, None)]); assert_eq!(result, expected); } diff --git a/core/src/storage_stage.rs b/core/src/storage_stage.rs index fff8198113..95878a89ce 100644 --- a/core/src/storage_stage.rs +++ b/core/src/storage_stage.rs @@ -449,10 +449,10 @@ mod tests { use crate::cluster_info::ClusterInfo; use crate::contact_info::ContactInfo; use crate::entry::{make_tiny_test_entries, Entry}; + use crate::genesis_utils::create_genesis_block; use crate::service::Service; use rayon::prelude::*; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::{Hash, Hasher}; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -471,7 +471,7 @@ mod tests { let exit = Arc::new(AtomicBool::new(false)); let cluster_info = test_cluster_info(&keypair.pubkey()); - let (genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, _mint_keypair) = create_genesis_block(1000); let bank = Arc::new(Bank::new(&genesis_block)); let bank_forks = Arc::new(RwLock::new(BankForks::new_from_banks(&[bank]))); let (_slot_sender, slot_receiver) = channel(); @@ -504,7 +504,7 @@ mod tests { let storage_keypair = Arc::new(Keypair::new()); let exit = Arc::new(AtomicBool::new(false)); - let (genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, _mint_keypair) = create_genesis_block(1000); let ticks_per_slot = genesis_block.ticks_per_slot; let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); @@ -577,7 +577,7 @@ mod tests { let storage_keypair = Arc::new(Keypair::new()); let exit = Arc::new(AtomicBool::new(false)); - let (genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, _mint_keypair) = create_genesis_block(1000); let ticks_per_slot = genesis_block.ticks_per_slot;; let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); diff --git a/core/src/tvu.rs b/core/src/tvu.rs index 7fa5d3c983..9f4736404f 100644 --- a/core/src/tvu.rs +++ b/core/src/tvu.rs @@ -180,9 +180,9 @@ pub mod tests { use crate::banking_stage::create_test_recorder; use crate::blocktree::get_tmp_ledger_path; use crate::cluster_info::{ClusterInfo, Node}; + use crate::genesis_utils::create_genesis_block; use crate::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana_runtime::bank::Bank; - use solana_sdk::genesis_block::GenesisBlock; use std::sync::atomic::Ordering; #[test] @@ -193,7 +193,7 @@ pub mod tests { let target1 = Node::new_localhost_with_pubkey(&target1_keypair.pubkey()); let starting_balance = 10_000; - let (genesis_block, _mint_keypair) = GenesisBlock::new(starting_balance); + let (genesis_block, _mint_keypair) = create_genesis_block(starting_balance); let bank_forks = BankForks::new(0, Bank::new(&genesis_block)); diff --git a/core/src/window_service.rs b/core/src/window_service.rs index 6ff25ccf66..a20ff23f0e 100644 --- a/core/src/window_service.rs +++ b/core/src/window_service.rs @@ -252,11 +252,11 @@ mod test { use crate::blocktree::{get_tmp_ledger_path, Blocktree}; use crate::cluster_info::{ClusterInfo, Node}; use crate::entry::{make_consecutive_blobs, make_tiny_test_entries, EntrySlice}; + use crate::genesis_utils::create_genesis_block_with_leader; use crate::packet::{index_blobs, Blob}; use crate::service::Service; use crate::streamer::{blob_receiver, responder}; use solana_runtime::bank::{Bank, MINIMUM_SLOT_LENGTH}; - use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::hash::Hash; use std::fs::remove_dir_all; use std::net::UdpSocket; @@ -293,7 +293,7 @@ mod test { let me_id = Pubkey::new_rand(); let leader_id = Pubkey::new_rand(); let bank = Arc::new(Bank::new( - &GenesisBlock::new_with_leader(100, &leader_id, 10).0, + &create_genesis_block_with_leader(100, &leader_id, 10).0, )); let cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank)); @@ -355,7 +355,7 @@ mod test { Blocktree::open(&blocktree_path).expect("Expected to be able to open database ledger"), ); - let bank = Bank::new(&GenesisBlock::new_with_leader(100, &me_id, 10).0); + let bank = Bank::new(&create_genesis_block_with_leader(100, &me_id, 10).0); let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank)); let bank_forks = Some(Arc::new(RwLock::new(BankForks::new(0, bank)))); let t_window = WindowService::new( @@ -433,7 +433,7 @@ mod test { let blocktree = Arc::new( Blocktree::open(&blocktree_path).expect("Expected to be able to open database ledger"), ); - let bank = Bank::new(&GenesisBlock::new_with_leader(100, &me_id, 10).0); + let bank = Bank::new(&create_genesis_block_with_leader(100, &me_id, 10).0); let leader_schedule_cache = Arc::new(LeaderScheduleCache::new_from_bank(&bank)); let bank_forks = Some(Arc::new(RwLock::new(BankForks::new(0, bank)))); let t_window = WindowService::new( diff --git a/core/tests/replicator.rs b/core/tests/replicator.rs index ea432040c9..1cab706ecb 100644 --- a/core/tests/replicator.rs +++ b/core/tests/replicator.rs @@ -16,7 +16,7 @@ use solana::replicator::ReplicatorRequest; use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::streamer::blob_receiver; use solana_client::thin_client::create_client; -use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::hash::Hash; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::fs::remove_dir_all; @@ -153,7 +153,7 @@ fn test_replicator_startup_leader_hang() { info!("starting replicator test"); let leader_ledger_path = "replicator_test_leader_ledger"; - let (genesis_block, _mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, _mint_keypair) = create_genesis_block(10_000); let (replicator_ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); { diff --git a/core/tests/tvu.rs b/core/tests/tvu.rs index c5ecb247ad..f5cb836634 100644 --- a/core/tests/tvu.rs +++ b/core/tests/tvu.rs @@ -8,6 +8,7 @@ use solana::cluster_info::{ClusterInfo, Node}; use solana::entry::next_entry_mut; use solana::entry::EntrySlice; use solana::fullnode; +use solana::genesis_utils::create_genesis_block_with_leader; use solana::gossip_service::GossipService; use solana::packet::index_blobs; use solana::rpc_subscriptions::RpcSubscriptions; @@ -17,7 +18,6 @@ use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::streamer; use solana::tvu::{Sockets, Tvu}; use solana_runtime::bank::MINIMUM_SLOT_LENGTH; -use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction; use std::fs::remove_dir_all; @@ -73,11 +73,10 @@ fn test_replay() { r_responder, ); - let total_balance = 10_000; + let mint_balance = 10_000; let leader_balance = 100; - let starting_mint_balance = total_balance - leader_balance; - let (mut genesis_block, mint_keypair) = - GenesisBlock::new_with_leader(total_balance, &leader.info.id, leader_balance); + let (mut genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(mint_balance, &leader.info.id, leader_balance); genesis_block.ticks_per_slot = 160; genesis_block.slots_per_epoch = MINIMUM_SLOT_LENGTH as u64; let (blocktree_path, blockhash) = create_new_tmp_ledger!(&genesis_block); @@ -87,10 +86,7 @@ fn test_replay() { let (bank_forks, _bank_forks_info, blocktree, ledger_signal_receiver, leader_schedule_cache) = fullnode::new_banks_from_blocktree(&blocktree_path, None); let bank = bank_forks.working_bank(); - assert_eq!( - bank.get_balance(&mint_keypair.pubkey()), - starting_mint_balance - ); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), mint_balance); let leader_schedule_cache = Arc::new(leader_schedule_cache); // start cluster_info1 @@ -129,7 +125,7 @@ fn test_replay() { &solana_sdk::hash::Hash::default(), ); - let mut mint_ref_balance = starting_mint_balance; + let mut mint_ref_balance = mint_balance; let mut msgs = Vec::new(); let mut blob_idx = 0; let num_transfers = 10; @@ -179,7 +175,7 @@ fn test_replay() { assert_eq!(final_mint_balance, mint_ref_balance); let bob_balance = working_bank.get_balance(&bob_keypair.pubkey()); - assert_eq!(bob_balance, starting_mint_balance - mint_ref_balance); + assert_eq!(bob_balance, mint_balance - mint_ref_balance); exit.store(true, Ordering::Relaxed); poh_service_exit.store(true, Ordering::Relaxed); diff --git a/genesis/Cargo.toml b/genesis/Cargo.toml index c99766d0e7..f017640aa9 100644 --- a/genesis/Cargo.toml +++ b/genesis/Cargo.toml @@ -14,6 +14,7 @@ serde_json = "1.0.39" solana = { path = "../core", version = "0.15.0" } solana-sdk = { path = "../sdk", version = "0.15.0" } solana-budget-api = { path = "../programs/budget_api", version = "0.15.0" } +solana-vote-api = { path = "../programs/vote_api", version = "0.15.0" } solana-stake-api = { path = "../programs/stake_api", version = "0.15.0" } solana-storage-api = { path = "../programs/storage_api", version = "0.15.0" } solana-token-api = { path = "../programs/token_api", version = "0.15.0" } @@ -23,7 +24,6 @@ solana-exchange-api = { path = "../programs/exchange_api", version = "0.15.0" } [dev-dependencies] hashbrown = "0.3.0" -solana-vote-api = { path = "../programs/vote_api", version = "0.15.0" } [features] cuda = ["solana/cuda"] diff --git a/genesis/src/main.rs b/genesis/src/main.rs index f175464d34..d1bfa69711 100644 --- a/genesis/src/main.rs +++ b/genesis/src/main.rs @@ -2,16 +2,14 @@ use clap::{crate_description, crate_name, crate_version, value_t_or_exit, App, Arg}; use solana::blocktree::create_new_ledger; +use solana_sdk::account::Account; use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::signature::{read_keypair, KeypairUtil}; +use solana_sdk::system_program; +use solana_vote_api::vote_state; use std::error; -/** - * Bootstrap leader gets two lamports: - * - 42 lamports to use as stake - * - One lamport to keep the node identity public key valid - */ -pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 43; +pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 42; fn main() -> Result<(), Box> { let default_bootstrap_leader_lamports = &BOOTSTRAP_LEADER_LAMPORTS.to_string(); @@ -85,16 +83,30 @@ fn main() -> Result<(), Box> { let bootstrap_vote_keypair = read_keypair(bootstrap_vote_keypair_file)?; let mint_keypair = read_keypair(mint_keypair_file)?; - let (mut genesis_block, _mint_keypair) = GenesisBlock::new_with_leader( - lamports, + let genesis_block = GenesisBlock::new( &bootstrap_leader_keypair.pubkey(), - bootstrap_leader_lamports, - ); - genesis_block.mint_id = mint_keypair.pubkey(); - genesis_block.bootstrap_leader_vote_account_id = bootstrap_vote_keypair.pubkey(); - genesis_block - .native_instruction_processors - .extend_from_slice(&[ + &[ + ( + mint_keypair.pubkey(), + Account::new( + lamports - bootstrap_leader_lamports, + 0, + &system_program::id(), + ), + ), + ( + bootstrap_vote_keypair.pubkey(), + vote_state::create_bootstrap_leader_account( + &bootstrap_vote_keypair.pubkey(), + &bootstrap_leader_keypair.pubkey(), + 0, + bootstrap_leader_lamports, + ), + ), + ], + &[ + ("solana_vote_program".to_string(), solana_vote_api::id()), + ("solana_stake_program".to_string(), solana_stake_api::id()), ("solana_budget_program".to_string(), solana_budget_api::id()), ( "solana_storage_program".to_string(), @@ -106,7 +118,8 @@ fn main() -> Result<(), Box> { "solana_exchange_program".to_string(), solana_exchange_api::id(), ), - ]); + ], + ); create_new_ledger(ledger_path, &genesis_block)?; Ok(()) @@ -115,52 +128,56 @@ fn main() -> Result<(), Box> { #[cfg(test)] mod tests { use hashbrown::HashSet; - use solana_sdk::pubkey::Pubkey; #[test] fn test_program_ids() { - let system = Pubkey::new(&[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - ]); - let native_loader = "NativeLoader1111111111111111111111111111111" - .parse::() - .unwrap(); - let bpf_loader = "BPFLoader1111111111111111111111111111111111" - .parse::() - .unwrap(); - let budget = "Budget1111111111111111111111111111111111111" - .parse::() - .unwrap(); - let stake = "Stake11111111111111111111111111111111111111" - .parse::() - .unwrap(); - let storage = "Storage111111111111111111111111111111111111" - .parse::() - .unwrap(); - let token = "Token11111111111111111111111111111111111111" - .parse::() - .unwrap(); - let vote = "Vote111111111111111111111111111111111111111" - .parse::() - .unwrap(); - let config = "Config1111111111111111111111111111111111111" - .parse::() - .unwrap(); - let exchange = "Exchange11111111111111111111111111111111111" - .parse::() - .unwrap(); - - assert_eq!(solana_sdk::system_program::id(), system); - assert_eq!(solana_sdk::native_loader::id(), native_loader); - assert_eq!(solana_sdk::bpf_loader::id(), bpf_loader); - assert_eq!(solana_budget_api::id(), budget); - assert_eq!(solana_stake_api::id(), stake); - assert_eq!(solana_storage_api::id(), storage); - assert_eq!(solana_token_api::id(), token); - assert_eq!(solana_vote_api::id(), vote); - assert_eq!(solana_config_api::id(), config); - assert_eq!(solana_exchange_api::id(), exchange); + let ids = [ + ( + "11111111111111111111111111111111", + solana_sdk::system_program::id(), + ), + ( + "NativeLoader1111111111111111111111111111111", + solana_sdk::native_loader::id(), + ), + ( + "BPFLoader1111111111111111111111111111111111", + solana_sdk::bpf_loader::id(), + ), + ( + "Budget1111111111111111111111111111111111111", + solana_budget_api::id(), + ), + ( + "Stake11111111111111111111111111111111111111", + solana_stake_api::id(), + ), + ( + "Storage111111111111111111111111111111111111", + solana_storage_api::id(), + ), + ( + "Token11111111111111111111111111111111111111", + solana_token_api::id(), + ), + ( + "Vote111111111111111111111111111111111111111", + solana_vote_api::id(), + ), + ( + "Stake11111111111111111111111111111111111111", + solana_stake_api::id(), + ), + ( + "Config1111111111111111111111111111111111111", + solana_config_api::id(), + ), + ( + "Exchange11111111111111111111111111111111111", + solana_exchange_api::id(), + ), + ]; + assert!(ids.iter().all(|(name, id)| *name == id.to_string())); } #[test] @@ -174,6 +191,7 @@ mod tests { solana_storage_api::id(), solana_token_api::id(), solana_vote_api::id(), + solana_stake_api::id(), solana_config_api::id(), solana_exchange_api::id(), ]; diff --git a/ledger-tool/tests/basic.rs b/ledger-tool/tests/basic.rs index 68f1436803..0557457517 100644 --- a/ledger-tool/tests/basic.rs +++ b/ledger-tool/tests/basic.rs @@ -3,11 +3,9 @@ extern crate solana; use assert_cmd::prelude::*; use solana::blocktree::create_new_tmp_ledger; -use solana_sdk::genesis_block::GenesisBlock; -use solana_sdk::signature::{Keypair, KeypairUtil}; +use solana::genesis_utils::create_genesis_block; use std::process::Command; use std::process::Output; -use std::sync::Arc; fn run_ledger_tool(args: &[&str]) -> Output { Command::cargo_bin(env!("CARGO_PKG_NAME")) @@ -34,8 +32,7 @@ fn bad_arguments() { #[test] fn nominal() { - let keypair = Arc::new(Keypair::new()); - let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(100, &keypair.pubkey(), 50); + let genesis_block = create_genesis_block(100).0; let ticks_per_slot = genesis_block.ticks_per_slot; let (ledger_path, _blockhash) = create_new_tmp_ledger!(&genesis_block); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index ca45cea6d8..b1af1ba257 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -3,7 +3,7 @@ mod bpf { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_runtime::loader_utils::{create_invoke_instruction, load_program}; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::native_loader; use std::env; use std::fs::File; @@ -40,7 +40,7 @@ mod bpf { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let (genesis_block, alice_keypair) = GenesisBlock::new(50); + let (genesis_block, alice_keypair) = create_genesis_block(50); let bank = Bank::new(&genesis_block); let bank_client = BankClient::new(bank); @@ -71,7 +71,7 @@ mod bpf { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let (genesis_block, alice_keypair) = GenesisBlock::new(50); + let (genesis_block, alice_keypair) = create_genesis_block(50); let bank = Bank::new(&genesis_block); let bank_client = BankClient::new(bank); @@ -116,7 +116,7 @@ mod bpf { let mut elf = Vec::new(); file.read_to_end(&mut elf).unwrap(); - let (genesis_block, alice_keypair) = GenesisBlock::new(50); + let (genesis_block, alice_keypair) = create_genesis_block(50); let bank = Bank::new(&genesis_block); let bank_client = BankClient::new(bank); diff --git a/programs/budget_api/src/budget_processor.rs b/programs/budget_api/src/budget_processor.rs index 5c510b4cbe..fa172d00e6 100644 --- a/programs/budget_api/src/budget_processor.rs +++ b/programs/budget_api/src/budget_processor.rs @@ -148,14 +148,14 @@ mod tests { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::instruction::InstructionError; use solana_sdk::message::Message; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::transaction::TransactionError; fn create_bank(lamports: u64) -> (Bank, Keypair) { - let (genesis_block, mint_keypair) = GenesisBlock::new(lamports); + let (genesis_block, mint_keypair) = create_genesis_block(lamports); let mut bank = Bank::new(&genesis_block); bank.add_instruction_processor(id(), process_instruction); (bank, mint_keypair) diff --git a/programs/config_api/src/config_processor.rs b/programs/config_api/src/config_processor.rs index 7b6a685976..67a0db9eb7 100644 --- a/programs/config_api/src/config_processor.rs +++ b/programs/config_api/src/config_processor.rs @@ -34,7 +34,7 @@ mod tests { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::message::Message; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction; @@ -59,7 +59,7 @@ mod tests { } fn create_bank(lamports: u64) -> (Bank, Keypair) { - let (genesis_block, mint_keypair) = GenesisBlock::new(lamports); + let (genesis_block, mint_keypair) = create_genesis_block(lamports); let mut bank = Bank::new(&genesis_block); bank.add_instruction_processor(id(), process_instruction); (bank, mint_keypair) diff --git a/programs/exchange_api/src/exchange_processor.rs b/programs/exchange_api/src/exchange_processor.rs index f9575dc607..8517bbe590 100644 --- a/programs/exchange_api/src/exchange_processor.rs +++ b/programs/exchange_api/src/exchange_processor.rs @@ -464,7 +464,7 @@ mod test { use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction; use std::mem; @@ -547,7 +547,7 @@ mod test { } fn create_bank(lamports: u64) -> (Bank, Keypair) { - let (genesis_block, mint_keypair) = GenesisBlock::new(lamports); + let (genesis_block, mint_keypair) = create_genesis_block(lamports); let mut bank = Bank::new(&genesis_block); bank.add_instruction_processor(id(), process_instruction); (bank, mint_keypair) diff --git a/programs/failure_program/tests/failure.rs b/programs/failure_program/tests/failure.rs index 7ab97f8743..0c8b1015e4 100644 --- a/programs/failure_program/tests/failure.rs +++ b/programs/failure_program/tests/failure.rs @@ -2,7 +2,7 @@ use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_runtime::loader_utils::{create_invoke_instruction, load_program}; use solana_sdk::client::SyncClient; -use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::instruction::InstructionError; use solana_sdk::native_loader; use solana_sdk::signature::KeypairUtil; @@ -10,7 +10,7 @@ use solana_sdk::transaction::TransactionError; #[test] fn test_program_native_failure() { - let (genesis_block, alice_keypair) = GenesisBlock::new(50); + let (genesis_block, alice_keypair) = create_genesis_block(50); let bank = Bank::new(&genesis_block); let bank_client = BankClient::new(bank); diff --git a/programs/noop_program/tests/noop.rs b/programs/noop_program/tests/noop.rs index 78990bffbd..5193ab5a0f 100644 --- a/programs/noop_program/tests/noop.rs +++ b/programs/noop_program/tests/noop.rs @@ -2,7 +2,7 @@ use solana_runtime::bank::Bank; use solana_runtime::bank_client::BankClient; use solana_runtime::loader_utils::{create_invoke_instruction, load_program}; use solana_sdk::client::SyncClient; -use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::native_loader; use solana_sdk::signature::KeypairUtil; @@ -10,7 +10,7 @@ use solana_sdk::signature::KeypairUtil; fn test_program_native_noop() { solana_logger::setup(); - let (genesis_block, alice_keypair) = GenesisBlock::new(50); + let (genesis_block, alice_keypair) = create_genesis_block(50); let bank = Bank::new(&genesis_block); let bank_client = BankClient::new(bank); diff --git a/programs/storage_api/src/storage_processor.rs b/programs/storage_api/src/storage_processor.rs index 695d1ffedf..518b157e2e 100644 --- a/programs/storage_api/src/storage_processor.rs +++ b/programs/storage_api/src/storage_processor.rs @@ -83,7 +83,7 @@ mod tests { use solana_runtime::bank_client::BankClient; use solana_sdk::account::{create_keyed_accounts, Account}; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::hash::{hash, Hash}; use solana_sdk::instruction::Instruction; use solana_sdk::pubkey::Pubkey; @@ -180,7 +180,7 @@ mod tests { #[ignore] fn test_validate_mining() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let mint_pubkey = mint_keypair.pubkey(); let replicator_keypair = Keypair::new(); let replicator = replicator_keypair.pubkey(); @@ -312,7 +312,7 @@ mod tests { #[test] fn test_bank_storage() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let (genesis_block, mint_keypair) = create_genesis_block(1000); let mint_pubkey = mint_keypair.pubkey(); let replicator_keypair = Keypair::new(); let replicator_pubkey = replicator_keypair.pubkey(); diff --git a/programs/vote_api/src/vote_state.rs b/programs/vote_api/src/vote_state.rs index 0683bcbce2..f4910b8316 100644 --- a/programs/vote_api/src/vote_state.rs +++ b/programs/vote_api/src/vote_state.rs @@ -271,6 +271,21 @@ pub fn create_account( vote_account } +// utility function, used by solana-genesis, tests +pub fn create_bootstrap_leader_account( + vote_id: &Pubkey, + node_id: &Pubkey, + commission: u32, + lamports: u64, +) -> Account { + // Construct a vote account for the bootstrap_leader such that the leader_scheduler + // will be forced to select it as the leader for height 0 + let mut account = create_account(&vote_id, &node_id, commission, lamports); + + vote(&vote_id, &mut account, &Vote::new(0)).unwrap(); + account +} + // utility function, used by Bank, tests pub fn vote( vote_id: &Pubkey, diff --git a/runtime/benches/accounts.rs b/runtime/benches/accounts.rs index ee3bb62ad3..29f9bf7c53 100644 --- a/runtime/benches/accounts.rs +++ b/runtime/benches/accounts.rs @@ -4,7 +4,7 @@ extern crate test; use solana_runtime::bank::*; use solana_sdk::account::Account; -use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::pubkey::Pubkey; use std::sync::Arc; use test::Bencher; @@ -22,7 +22,7 @@ fn deposit_many(bank: &Bank, pubkeys: &mut Vec, num: usize) { #[bench] fn test_accounts_create(bencher: &mut Bencher) { - let (genesis_block, _) = GenesisBlock::new(10_000); + let (genesis_block, _) = create_genesis_block(10_000); let bank0 = Bank::new_with_paths(&genesis_block, Some("bench_a0".to_string())); bencher.iter(|| { let mut pubkeys: Vec = vec![]; @@ -32,7 +32,7 @@ fn test_accounts_create(bencher: &mut Bencher) { #[bench] fn test_accounts_squash(bencher: &mut Bencher) { - let (genesis_block, _) = GenesisBlock::new(100_000); + let (genesis_block, _) = create_genesis_block(100_000); let mut banks: Vec> = Vec::with_capacity(10); banks.push(Arc::new(Bank::new_with_paths( &genesis_block, diff --git a/runtime/benches/bank.rs b/runtime/benches/bank.rs index 5207a5a828..ca7c9ef85c 100644 --- a/runtime/benches/bank.rs +++ b/runtime/benches/bank.rs @@ -9,7 +9,7 @@ use solana_runtime::loader_utils::{create_invoke_instruction, load_program}; use solana_sdk::account::KeyedAccount; use solana_sdk::client::AsyncClient; use solana_sdk::client::SyncClient; -use solana_sdk::genesis_block::GenesisBlock; +use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::instruction::InstructionError; use solana_sdk::native_loader; use solana_sdk::pubkey::Pubkey; @@ -124,7 +124,7 @@ fn do_bench_transactions( ) { solana_logger::setup(); let ns_per_s = 1_000_000_000; - let (genesis_block, mint_keypair) = GenesisBlock::new(100_000_000); + let (genesis_block, mint_keypair) = create_genesis_block(100_000_000); let mut bank = Bank::new(&genesis_block); bank.add_instruction_processor(Pubkey::new(&BUILTIN_PROGRAM_ID), process_instruction); let bank = Arc::new(bank); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index a246869fee..d9c5b68b53 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -25,7 +25,7 @@ use solana_sdk::signature::{Keypair, Signature}; use solana_sdk::system_transaction; use solana_sdk::timing::{duration_as_ms, duration_as_us, MAX_RECENT_BLOCKHASHES}; use solana_sdk::transaction::{Result, Transaction, TransactionError}; -use solana_vote_api::vote_state::{self, Vote, MAX_LOCKOUT_HISTORY}; +use solana_vote_api::vote_state::MAX_LOCKOUT_HISTORY; use std::cmp; use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, RwLock}; @@ -337,46 +337,12 @@ impl Bank { } fn process_genesis_block(&mut self, genesis_block: &GenesisBlock) { - assert!(genesis_block.mint_id != Pubkey::default()); - assert!(genesis_block.bootstrap_leader_id != Pubkey::default()); - assert!(genesis_block.bootstrap_leader_vote_account_id != Pubkey::default()); - assert!(genesis_block.lamports >= genesis_block.bootstrap_leader_lamports); - assert!(genesis_block.bootstrap_leader_lamports >= 2); - // Bootstrap leader collects fees until `new_from_parent` is called. self.collector_id = genesis_block.bootstrap_leader_id; - let mint_lamports = genesis_block.lamports - genesis_block.bootstrap_leader_lamports; - self.deposit(&genesis_block.mint_id, mint_lamports); - - let bootstrap_leader_lamports = 1; - let bootstrap_leader_stake = - genesis_block.bootstrap_leader_lamports - bootstrap_leader_lamports; - self.deposit( - &genesis_block.bootstrap_leader_id, - bootstrap_leader_lamports, - ); - - // Construct a vote account for the bootstrap_leader such that the leader_scheduler - // will be forced to select it as the leader for height 0 - let mut bootstrap_leader_vote_account = vote_state::create_account( - &genesis_block.bootstrap_leader_vote_account_id, - &genesis_block.bootstrap_leader_id, - 0, - bootstrap_leader_stake, - ); - - vote_state::vote( - &genesis_block.bootstrap_leader_vote_account_id, - &mut bootstrap_leader_vote_account, - &Vote::new(0), - ) - .unwrap(); - - self.store( - &genesis_block.bootstrap_leader_vote_account_id, - &bootstrap_leader_vote_account, - ); + for (pubkey, account) in genesis_block.accounts.iter() { + self.store(pubkey, account); + } self.blockhash_queue .write() @@ -1050,52 +1016,74 @@ impl Drop for Bank { } #[cfg(test)] -mod tests { +pub(crate) mod tests { use super::*; - use solana_sdk::genesis_block::{GenesisBlock, BOOTSTRAP_LEADER_LAMPORTS}; + + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::hash; use solana_sdk::instruction::InstructionError; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_instruction; + use solana_sdk::system_program; use solana_sdk::system_transaction; use solana_vote_api::vote_instruction; - use solana_vote_api::vote_state::VoteState; + use solana_vote_api::vote_state::{self, VoteState}; - #[test] - fn test_bank_new_no_parent() { - solana_logger::setup(); - let (genesis_block, _) = GenesisBlock::new(10_000); - let bank = Bank::new(&genesis_block); - trace!("get balance {}", genesis_block.mint_id); - let bal = bank.get_balance(&genesis_block.mint_id); - trace!("done get balance {}", bal); - assert_eq!(bal, 10_000); + // The default stake placed with the bootstrap leader + pub(crate) const BOOTSTRAP_LEADER_LAMPORTS: u64 = 42; + + pub(crate) fn create_genesis_block_with_leader( + mint_lamports: u64, + leader_id: &Pubkey, + leader_stake_lamports: u64, + ) -> (GenesisBlock, Keypair, Keypair) { + let mint_keypair = Keypair::new(); + let voting_keypair = Keypair::new(); + + let genesis_block = GenesisBlock::new( + &leader_id, + &[ + ( + mint_keypair.pubkey(), + Account::new(mint_lamports, 0, &system_program::id()), + ), + ( + voting_keypair.pubkey(), + vote_state::create_bootstrap_leader_account( + &voting_keypair.pubkey(), + &leader_id, + 0, + leader_stake_lamports, + ), + ), + ], + &[], + ); + + (genesis_block, mint_keypair, voting_keypair) } #[test] - fn test_bank_new_with_leader() { + fn test_bank_new() { let dummy_leader_id = Pubkey::new_rand(); let dummy_leader_lamports = BOOTSTRAP_LEADER_LAMPORTS; - let (genesis_block, _) = - GenesisBlock::new_with_leader(10_000, &dummy_leader_id, dummy_leader_lamports); - assert_eq!( - genesis_block.bootstrap_leader_lamports, - dummy_leader_lamports + let mint_lamports = 10_000; + let (genesis_block, mint_keypair, voting_keypair) = create_genesis_block_with_leader( + mint_lamports, + &dummy_leader_id, + dummy_leader_lamports, ); let bank = Bank::new(&genesis_block); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), mint_lamports); assert_eq!( - bank.get_balance(&genesis_block.mint_id), - 10_000 - dummy_leader_lamports - ); - assert_eq!( - bank.get_balance(&dummy_leader_id), - dummy_leader_lamports - 1 /* 1 token goes to the vote account associated with dummy_leader_lamports */ + bank.get_balance(&voting_keypair.pubkey()), + dummy_leader_lamports /* 1 token goes to the vote account associated with dummy_leader_lamports */ ); } #[test] fn test_two_payments_to_one_party() { - let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, mint_keypair) = create_genesis_block(10_000); let pubkey = Pubkey::new_rand(); let bank = Bank::new(&genesis_block); assert_eq!(bank.last_blockhash(), genesis_block.hash()); @@ -1110,7 +1098,7 @@ mod tests { #[test] fn test_one_source_two_tx_one_batch() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let (genesis_block, mint_keypair) = create_genesis_block(1); let key1 = Pubkey::new_rand(); let key2 = Pubkey::new_rand(); let bank = Bank::new(&genesis_block); @@ -1133,7 +1121,7 @@ mod tests { #[test] fn test_one_tx_two_out_atomic_fail() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let (genesis_block, mint_keypair) = create_genesis_block(1); let key1 = Pubkey::new_rand(); let key2 = Pubkey::new_rand(); let bank = Bank::new(&genesis_block); @@ -1158,7 +1146,7 @@ mod tests { #[test] fn test_one_tx_two_out_atomic_pass() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let key1 = Pubkey::new_rand(); let key2 = Pubkey::new_rand(); let bank = Bank::new(&genesis_block); @@ -1178,7 +1166,7 @@ mod tests { // This test demonstrates that fees are paid even when a program fails. #[test] fn test_detect_failed_duplicate_transactions() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let mut bank = Bank::new(&genesis_block); bank.fee_calculator.lamports_per_signature = 1; @@ -1212,7 +1200,7 @@ mod tests { #[test] fn test_account_not_found() { - let (genesis_block, mint_keypair) = GenesisBlock::new(0); + let (genesis_block, mint_keypair) = create_genesis_block(0); let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); assert_eq!( @@ -1224,7 +1212,7 @@ mod tests { #[test] fn test_insufficient_funds() { - let (genesis_block, mint_keypair) = GenesisBlock::new(11_000); + let (genesis_block, mint_keypair) = create_genesis_block(11_000); let bank = Bank::new(&genesis_block); let pubkey = Pubkey::new_rand(); bank.transfer(1_000, &mint_keypair, &pubkey).unwrap(); @@ -1246,7 +1234,7 @@ mod tests { #[test] fn test_transfer_to_newb() { - let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let (genesis_block, mint_keypair) = create_genesis_block(10_000); let bank = Bank::new(&genesis_block); let pubkey = Pubkey::new_rand(); bank.transfer(500, &mint_keypair, &pubkey).unwrap(); @@ -1255,7 +1243,7 @@ mod tests { #[test] fn test_bank_deposit() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(100); + let (genesis_block, _mint_keypair) = create_genesis_block(100); let bank = Bank::new(&genesis_block); // Test new account @@ -1270,7 +1258,7 @@ mod tests { #[test] fn test_bank_withdraw() { - let (genesis_block, _mint_keypair) = GenesisBlock::new(100); + let (genesis_block, _mint_keypair) = create_genesis_block(100); let bank = Bank::new(&genesis_block); // Test no account @@ -1297,7 +1285,8 @@ mod tests { #[test] fn test_bank_tx_fee() { let leader = Pubkey::new_rand(); - let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(100, &leader, 3); + let (genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(100, &leader, 3); let mut bank = Bank::new(&genesis_block); bank.fee_calculator.lamports_per_signature = 3; @@ -1310,7 +1299,7 @@ mod tests { assert_eq!(bank.process_transaction(&tx), Ok(())); assert_eq!(bank.get_balance(&leader), initial_balance + 3); assert_eq!(bank.get_balance(&key1.pubkey()), 2); - assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5 - 3); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5); bank.fee_calculator.lamports_per_signature = 1; let tx = system_transaction::transfer(&key1, &key2.pubkey(), 1, genesis_block.hash(), 0); @@ -1319,7 +1308,7 @@ mod tests { assert_eq!(bank.get_balance(&leader), initial_balance + 4); assert_eq!(bank.get_balance(&key1.pubkey()), 0); assert_eq!(bank.get_balance(&key2.pubkey()), 1); - assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5 - 3); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5); // verify that an InstructionError collects fees, too let mut tx = @@ -1330,14 +1319,15 @@ mod tests { bank.process_transaction(&tx) .expect_err("instruction error"); // fails with an instruction error assert_eq!(bank.get_balance(&leader), initial_balance + 5); // gots our bucks - assert_eq!(bank.get_balance(&key2.pubkey()), 1); // our fee ------V - assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5 - 3 - 1); + assert_eq!(bank.get_balance(&key2.pubkey()), 1); // our fee --V + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5 - 1); } #[test] fn test_filter_program_errors_and_collect_fee() { let leader = Pubkey::new_rand(); - let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(100, &leader, 3); + let (genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(100, &leader, 3); let mut bank = Bank::new(&genesis_block); let key = Keypair::new(); @@ -1364,7 +1354,7 @@ mod tests { #[test] fn test_debits_before_credits() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); let tx0 = system_transaction::create_user_account( @@ -1389,20 +1379,9 @@ mod tests { assert_eq!(bank.transaction_count(), 1); } - #[test] - fn test_process_genesis() { - let dummy_leader_id = Pubkey::new_rand(); - let dummy_leader_lamports = 2; - let (genesis_block, _) = - GenesisBlock::new_with_leader(5, &dummy_leader_id, dummy_leader_lamports); - let bank = Bank::new(&genesis_block); - assert_eq!(bank.get_balance(&genesis_block.mint_id), 3); - assert_eq!(bank.get_balance(&dummy_leader_id), 1); - } - #[test] fn test_interleaving_locks() { - let (genesis_block, mint_keypair) = GenesisBlock::new(3); + let (genesis_block, mint_keypair) = create_genesis_block(3); let bank = Bank::new(&genesis_block); let alice = Keypair::new(); let bob = Keypair::new(); @@ -1443,7 +1422,7 @@ mod tests { #[test] fn test_bank_invalid_account_index() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let (genesis_block, mint_keypair) = create_genesis_block(1); let keypair = Keypair::new(); let bank = Bank::new(&genesis_block); @@ -1472,7 +1451,7 @@ mod tests { #[test] fn test_bank_pay_to_self() { - let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let (genesis_block, mint_keypair) = create_genesis_block(1); let key1 = Keypair::new(); let bank = Bank::new(&genesis_block); @@ -1498,7 +1477,7 @@ mod tests { /// Verify that the parent's vector is computed correctly #[test] fn test_bank_parents() { - let (genesis_block, _) = GenesisBlock::new(1); + let (genesis_block, _) = create_genesis_block(1); let parent = Arc::new(Bank::new(&genesis_block)); let bank = new_from_parent(&parent); @@ -1508,7 +1487,7 @@ mod tests { /// Verifies that last ids and status cache are correctly referenced from parent #[test] fn test_bank_parent_duplicate_signature() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let key1 = Keypair::new(); let parent = Arc::new(Bank::new(&genesis_block)); @@ -1525,7 +1504,7 @@ mod tests { /// Verifies that last ids and accounts are correctly referenced from parent #[test] fn test_bank_parent_account_spend() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let key1 = Keypair::new(); let key2 = Keypair::new(); let parent = Arc::new(Bank::new(&genesis_block)); @@ -1541,7 +1520,7 @@ mod tests { #[test] fn test_bank_hash_internal_state() { - let (genesis_block, mint_keypair) = GenesisBlock::new(2_000); + let (genesis_block, mint_keypair) = create_genesis_block(2_000); let bank0 = Bank::new(&genesis_block); let bank1 = Bank::new(&genesis_block); let initial_state = bank0.hash_internal_state(); @@ -1560,15 +1539,15 @@ mod tests { #[test] fn test_hash_internal_state_genesis() { - let bank0 = Bank::new(&GenesisBlock::new(10).0); - let bank1 = Bank::new(&GenesisBlock::new(20).0); + let bank0 = Bank::new(&create_genesis_block(10).0); + let bank1 = Bank::new(&create_genesis_block(20).0); assert_ne!(bank0.hash_internal_state(), bank1.hash_internal_state()); } #[test] fn test_bank_hash_internal_state_squash() { let collector_id = Pubkey::default(); - let bank0 = Arc::new(Bank::new(&GenesisBlock::new(10).0)); + let bank0 = Arc::new(Bank::new(&create_genesis_block(10).0)); let bank1 = Bank::new_from_parent(&bank0, &collector_id, 1); // no delta in bank1, hashes match @@ -1586,7 +1565,7 @@ mod tests { #[test] fn test_bank_squash() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let (genesis_block, mint_keypair) = create_genesis_block(2); let key1 = Keypair::new(); let key2 = Keypair::new(); let parent = Arc::new(Bank::new(&genesis_block)); @@ -1647,7 +1626,7 @@ mod tests { #[test] fn test_bank_get_account_in_parent_after_squash() { - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let parent = Arc::new(Bank::new(&genesis_block)); let key1 = Keypair::new(); @@ -1663,7 +1642,7 @@ mod tests { fn test_bank_epoch_vote_accounts() { let leader_id = Pubkey::new_rand(); let leader_lamports = 3; - let (mut genesis_block, _) = GenesisBlock::new_with_leader(5, &leader_id, leader_lamports); + let mut genesis_block = create_genesis_block_with_leader(5, &leader_id, leader_lamports).0; // set this up weird, forces future generation, odd mod(), etc. // this says: "stakes for epoch X should be generated at slot index 3 in epoch X-2... @@ -1724,7 +1703,7 @@ mod tests { #[test] fn test_zero_signatures() { solana_logger::setup(); - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let mut bank = Bank::new(&genesis_block); bank.fee_calculator.lamports_per_signature = 2; let key = Keypair::new(); @@ -1745,7 +1724,7 @@ mod tests { #[test] fn test_bank_get_slots_in_epoch() { - let (genesis_block, _) = GenesisBlock::new(500); + let (genesis_block, _) = create_genesis_block(500); let bank = Bank::new(&genesis_block); @@ -1808,7 +1787,7 @@ mod tests { #[test] fn test_is_delta_true() { - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let bank = Arc::new(Bank::new(&genesis_block)); let key1 = Keypair::new(); let tx_transfer_mint_to_1 = @@ -1819,7 +1798,7 @@ mod tests { #[test] fn test_is_votable() { - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let bank = Arc::new(Bank::new(&genesis_block)); let key1 = Keypair::new(); assert_eq!(bank.is_votable(), false); @@ -1840,7 +1819,7 @@ mod tests { #[test] fn test_bank_inherit_tx_count() { - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair) = create_genesis_block(500); let bank0 = Arc::new(Bank::new(&genesis_block)); // Bank 1 @@ -1880,7 +1859,8 @@ mod tests { #[test] fn test_bank_vote_accounts() { - let (genesis_block, mint_keypair) = GenesisBlock::new(500); + let (genesis_block, mint_keypair, _voting_keypair) = + create_genesis_block_with_leader(500, &Pubkey::new_rand(), 1); let bank = Arc::new(Bank::new(&genesis_block)); let vote_accounts = bank.vote_accounts(); @@ -1919,7 +1899,7 @@ mod tests { #[test] fn test_bank_0_votable() { - let (genesis_block, _) = GenesisBlock::new(500); + let (genesis_block, _) = create_genesis_block(500); let bank = Arc::new(Bank::new(&genesis_block)); //set tick height to max let max_tick_height = ((bank.slot + 1) * bank.ticks_per_slot - 1) as usize; @@ -1929,7 +1909,7 @@ mod tests { #[test] fn test_is_delta_with_no_committables() { - let (genesis_block, mint_keypair) = GenesisBlock::new(8000); + let (genesis_block, mint_keypair) = create_genesis_block(8000); let bank = Bank::new(&genesis_block); bank.is_delta.store(false, Ordering::Relaxed); diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index 96bbf7a26e..81e5b6d575 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -214,12 +214,12 @@ impl BankClient { #[cfg(test)] mod tests { use super::*; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::instruction::AccountMeta; #[test] fn test_bank_client_new_with_keypairs() { - let (genesis_block, john_doe_keypair) = GenesisBlock::new(10_000); + let (genesis_block, john_doe_keypair) = create_genesis_block(10_000); let john_pubkey = john_doe_keypair.pubkey(); let jane_doe_keypair = Keypair::new(); let jane_pubkey = jane_doe_keypair.pubkey(); diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index c7b69a4506..c0982f22d2 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -111,7 +111,7 @@ mod tests { use bincode::serialize; use solana_sdk::account::Account; use solana_sdk::client::SyncClient; - use solana_sdk::genesis_block::GenesisBlock; + use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::instruction::{AccountMeta, Instruction, InstructionError}; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_program; @@ -280,7 +280,7 @@ mod tests { #[test] fn test_system_unsigned_transaction() { - let (genesis_block, alice_keypair) = GenesisBlock::new(100); + let (genesis_block, alice_keypair) = create_genesis_block(100); let alice_pubkey = alice_keypair.pubkey(); let mallory_keypair = Keypair::new(); let mallory_pubkey = mallory_keypair.pubkey(); diff --git a/sdk/src/genesis_block.rs b/sdk/src/genesis_block.rs index a6e77d257b..0fbcea8319 100644 --- a/sdk/src/genesis_block.rs +++ b/sdk/src/genesis_block.rs @@ -1,63 +1,57 @@ //! The `genesis_block` module is a library for generating the chain's genesis block. +use crate::account::Account; use crate::hash::{hash, Hash}; use crate::pubkey::Pubkey; use crate::signature::{Keypair, KeypairUtil}; +use crate::system_program; use crate::timing::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_TICKS_PER_SLOT}; use std::fs::File; use std::io::Write; use std::path::Path; -// The default (and minimal) amount of lamports given to the bootstrap leader: -// * 1 lamports for the bootstrap leader ID account -// * 1 lamport for the bootstrap leader vote account -pub const BOOTSTRAP_LEADER_LAMPORTS: u64 = 2; - #[derive(Serialize, Deserialize, Debug)] pub struct GenesisBlock { pub bootstrap_leader_id: Pubkey, - pub bootstrap_leader_lamports: u64, - pub bootstrap_leader_vote_account_id: Pubkey, - pub mint_id: Pubkey, - pub lamports: u64, pub ticks_per_slot: u64, pub slots_per_epoch: u64, pub stakers_slot_offset: u64, pub epoch_warmup: bool, + pub accounts: Vec<(Pubkey, Account)>, pub native_instruction_processors: Vec<(String, Pubkey)>, } -impl GenesisBlock { - #[allow(clippy::new_ret_no_self)] - pub fn new(lamports: u64) -> (Self, Keypair) { - let lamports = lamports - .checked_add(BOOTSTRAP_LEADER_LAMPORTS) - .unwrap_or(lamports); - Self::new_with_leader(lamports, &Pubkey::new_rand(), BOOTSTRAP_LEADER_LAMPORTS) - } +// useful for basic tests +pub fn create_genesis_block(lamports: u64) -> (GenesisBlock, Keypair) { + let mint_keypair = Keypair::new(); + ( + GenesisBlock::new( + &Pubkey::default(), + &[( + mint_keypair.pubkey(), + Account::new(lamports, 0, &system_program::id()), + )], + &[], + ), + mint_keypair, + ) +} - pub fn new_with_leader( - lamports: u64, +impl GenesisBlock { + pub fn new( bootstrap_leader_id: &Pubkey, - bootstrap_leader_lamports: u64, - ) -> (Self, Keypair) { - let mint_keypair = Keypair::new(); - let bootstrap_leader_vote_account_keypair = Keypair::new(); - ( - Self { - bootstrap_leader_id: *bootstrap_leader_id, - bootstrap_leader_lamports, - bootstrap_leader_vote_account_id: bootstrap_leader_vote_account_keypair.pubkey(), - mint_id: mint_keypair.pubkey(), - lamports, - ticks_per_slot: DEFAULT_TICKS_PER_SLOT, - slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH, - stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH, - epoch_warmup: true, - native_instruction_processors: vec![], - }, - mint_keypair, - ) + accounts: &[(Pubkey, Account)], + native_instruction_processors: &[(String, Pubkey)], + ) -> Self { + Self { + bootstrap_leader_id: *bootstrap_leader_id, // TODO: leader_schedule to derive from actual stakes, instead ;) + ticks_per_slot: DEFAULT_TICKS_PER_SLOT, + slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH, + stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH, + epoch_warmup: true, + accounts: accounts.to_vec(), + native_instruction_processors: native_instruction_processors.to_vec(), + } } pub fn hash(&self) -> Hash { @@ -73,7 +67,11 @@ impl GenesisBlock { pub fn write(&self, ledger_path: &str) -> Result<(), std::io::Error> { let serialized = serde_json::to_string(self)?; - let mut file = File::create(&Path::new(ledger_path).join("genesis.json"))?; + + let dir = Path::new(ledger_path); + std::fs::create_dir_all(&dir)?; + + let mut file = File::create(&dir.join("genesis.json"))?; file.write_all(&serialized.into_bytes()) } } @@ -81,29 +79,46 @@ impl GenesisBlock { #[cfg(test)] mod tests { use super::*; + use crate::signature::{Keypair, KeypairUtil}; + + fn make_tmp_path(name: &str) -> String { + let out_dir = std::env::var("OUT_DIR").unwrap_or_else(|_| "target".to_string()); + let keypair = Keypair::new(); + + let path = format!("{}/tmp/{}-{}", out_dir, name, keypair.pubkey()); + + // whack any possible collision + let _ignored = std::fs::remove_dir_all(&path); + // whack any possible collision + let _ignored = std::fs::remove_file(&path); + + path + } #[test] - fn test_genesis_block_new() { - let (genesis_block, mint) = GenesisBlock::new(10_000); - assert_eq!(genesis_block.lamports, 10_000 + BOOTSTRAP_LEADER_LAMPORTS); - assert_eq!(genesis_block.mint_id, mint.pubkey()); - assert!(genesis_block.bootstrap_leader_id != Pubkey::default()); - assert!(genesis_block.bootstrap_leader_vote_account_id != Pubkey::default()); - assert_eq!( - genesis_block.bootstrap_leader_lamports, - BOOTSTRAP_LEADER_LAMPORTS + fn test_genesis_block() { + let mint_keypair = Keypair::new(); + let block = GenesisBlock::new( + &Pubkey::default(), + &[ + ( + mint_keypair.pubkey(), + Account::new(10_000, 0, &Pubkey::default()), + ), + (Pubkey::new_rand(), Account::new(1, 0, &Pubkey::default())), + ], + &[("hi".to_string(), Pubkey::new_rand())], ); + assert_eq!(block.accounts.len(), 2); + assert!(block.accounts.iter().any( + |(pubkey, account)| *pubkey == mint_keypair.pubkey() && account.lamports == 10_000 + )); + + let path = &make_tmp_path("genesis_block"); + block.write(&path).expect("write"); + let loaded_block = GenesisBlock::load(&path).expect("load"); + assert_eq!(block.hash(), loaded_block.hash()); + let _ignored = std::fs::remove_file(&path); } - #[test] - fn test_genesis_block_new_with_leader() { - let leader_keypair = Keypair::new(); - let (genesis_block, mint) = - GenesisBlock::new_with_leader(20_000, &leader_keypair.pubkey(), 123); - - assert_eq!(genesis_block.lamports, 20_000); - assert_eq!(genesis_block.mint_id, mint.pubkey()); - assert_eq!(genesis_block.bootstrap_leader_id, leader_keypair.pubkey()); - assert_eq!(genesis_block.bootstrap_leader_lamports, 123); - } }