From 4bb6549895d871a0beeef61372af64f4a9d0fe1f Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Thu, 24 Jan 2019 12:04:04 -0800 Subject: [PATCH] Genesis block is now a json file --- benches/bank.rs | 15 +- benches/banking_stage.rs | 42 +- book/src/terminology.md | 2 +- genesis/src/main.rs | 75 ++-- ledger-tool/src/main.rs | 32 +- src/bank.rs | 493 ++++++++------------- src/banking_stage.rs | 30 +- src/compute_leader_confirmation_service.rs | 8 +- src/db_ledger.rs | 83 ++-- src/fullnode.rs | 147 +++--- src/genesis_block.rs | 92 ++++ src/leader_scheduler.rs | 171 +++---- src/lib.rs | 2 +- src/mint.rs | 160 ------- src/poh_recorder.rs | 6 +- src/poh_service.rs | 6 +- src/replay_stage.rs | 69 +-- src/rpc.rs | 46 +- src/rpc_pubsub.rs | 46 +- src/storage_stage.rs | 4 +- src/thin_client.rs | 79 ++-- src/tvu.rs | 10 +- src/vote_signer_proxy.rs | 6 +- tests/multinode.rs | 148 ++++--- tests/programs.rs | 91 ++-- tests/replicator.rs | 19 +- tests/rpc.rs | 17 +- wallet/tests/deploy.rs | 17 +- wallet/tests/pay.rs | 43 +- wallet/tests/request_airdrop.rs | 17 +- 30 files changed, 924 insertions(+), 1052 deletions(-) create mode 100644 src/genesis_block.rs delete mode 100644 src/mint.rs diff --git a/benches/bank.rs b/benches/bank.rs index 9c8212621..84934f1f9 100644 --- a/benches/bank.rs +++ b/benches/bank.rs @@ -3,7 +3,7 @@ extern crate test; use solana::bank::*; -use solana::mint::Mint; +use solana::genesis_block::GenesisBlock; use solana::status_deque::MAX_ENTRY_IDS; use solana_sdk::hash::hash; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -13,8 +13,8 @@ use test::Bencher; #[bench] fn bench_process_transaction(bencher: &mut Bencher) { - let mint = Mint::new(100_000_000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(100_000_000); + let bank = Bank::new(&genesis_block); // Create transactions between unrelated parties. let transactions: Vec<_> = (0..4096) @@ -22,13 +22,8 @@ fn bench_process_transaction(bencher: &mut Bencher) { .map(|_| { // Seed the 'from' account. let rando0 = Keypair::new(); - let tx = Transaction::system_move( - &mint.keypair(), - rando0.pubkey(), - 10_000, - bank.last_id(), - 0, - ); + let tx = + Transaction::system_move(&mint_keypair, rando0.pubkey(), 10_000, bank.last_id(), 0); assert_eq!(bank.process_transaction(&tx), Ok(())); // Seed the 'to' account and a cell for its signature. diff --git a/benches/banking_stage.rs b/benches/banking_stage.rs index 869215f91..45be06b3f 100644 --- a/benches/banking_stage.rs +++ b/benches/banking_stage.rs @@ -7,7 +7,7 @@ use rayon::prelude::*; use solana::bank::Bank; use solana::banking_stage::BankingStage; use solana::entry::Entry; -use solana::mint::Mint; +use solana::genesis_block::GenesisBlock; use solana::packet::to_packets_chunked; use solana::status_deque::MAX_ENTRY_IDS; use solana_sdk::hash::hash; @@ -45,16 +45,16 @@ 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 mint = Mint::new(mint_total); + let (genesis_block, mint_keypair) = GenesisBlock::new(mint_total); let (verified_sender, verified_receiver) = channel(); - let bank = Arc::new(Bank::new(&mint)); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let dummy = Transaction::system_move( - &mint.keypair(), - mint.keypair().pubkey(), + &mint_keypair, + mint_keypair.pubkey(), 1, - mint.last_id(), + genesis_block.last_id(), 0, ); let transactions: Vec<_> = (0..txes) @@ -73,10 +73,10 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { // fund all the accounts transactions.iter().for_each(|tx| { let fund = Transaction::system_move( - &mint.keypair(), + &mint_keypair, tx.account_keys[0], mint_total / txes as u64, - mint.last_id(), + genesis_block.last_id(), 0, ); let x = bank.process_transaction(&fund); @@ -105,12 +105,12 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { &bank, verified_receiver, Default::default(), - &mint.last_id(), + &genesis_block.last_id(), None, dummy_leader_id, ); - let mut id = mint.last_id(); + let mut id = genesis_block.last_id(); for _ in 0..MAX_ENTRY_IDS { id = hash(&id.as_ref()); bank.register_tick(&id); @@ -120,7 +120,7 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) { let mut start = 0; bencher.iter(move || { // make sure the transactions are still valid - bank.register_tick(&mint.last_id()); + bank.register_tick(&genesis_block.last_id()); for v in verified[start..start + half_len].chunks(verified.len() / num_threads) { verified_sender.send(v.to_vec()).unwrap(); } @@ -138,16 +138,16 @@ 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 mint = Mint::new(mint_total); + let (genesis_block, mint_keypair) = GenesisBlock::new(mint_total); let (verified_sender, verified_receiver) = channel(); - let bank = Arc::new(Bank::new(&mint)); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let dummy = Transaction::system_move( - &mint.keypair(), - mint.keypair().pubkey(), + &mint_keypair, + mint_keypair.pubkey(), 1, - mint.last_id(), + genesis_block.last_id(), 0, ); let transactions: Vec<_> = (0..txes) @@ -182,10 +182,10 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { .collect(); transactions.iter().for_each(|tx| { let fund = Transaction::system_move( - &mint.keypair(), + &mint_keypair, tx.account_keys[0], mint_total / txes as u64, - mint.last_id(), + genesis_block.last_id(), 0, ); assert!(bank.process_transaction(&fund).is_ok()); @@ -213,12 +213,12 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { &bank, verified_receiver, Default::default(), - &mint.last_id(), + &genesis_block.last_id(), None, dummy_leader_id, ); - let mut id = mint.last_id(); + let mut id = genesis_block.last_id(); for _ in 0..MAX_ENTRY_IDS { id = hash(&id.as_ref()); bank.register_tick(&id); @@ -228,7 +228,7 @@ fn bench_banking_stage_multi_programs(bencher: &mut Bencher) { let mut start = 0; bencher.iter(move || { // make sure the transactions are still valid - bank.register_tick(&mint.last_id()); + bank.register_tick(&genesis_block.last_id()); for v in verified[start..start + half_len].chunks(verified.len() / num_threads) { verified_sender.send(v.to_vec()).unwrap(); } diff --git a/book/src/terminology.md b/book/src/terminology.md index 1ef136161..5dd9216f9 100644 --- a/book/src/terminology.md +++ b/book/src/terminology.md @@ -97,7 +97,7 @@ holding nonzero [native tokens](#native-tokens). #### genesis block -The first [block](#block) of the [ledger](#ledger). +The configuration file that prepares the [ledger](#ledger) for the first [block](#block). #### hash diff --git a/genesis/src/main.rs b/genesis/src/main.rs index 31f2f76f2..6a2e46a24 100644 --- a/genesis/src/main.rs +++ b/genesis/src/main.rs @@ -2,12 +2,10 @@ use clap::{crate_version, value_t_or_exit, App, Arg}; use serde_json; -use solana::db_ledger::genesis; -use solana::mint::Mint; +use solana::db_ledger::create_empty_ledger; +use solana::genesis_block::GenesisBlock; use solana_sdk::signature::{read_keypair, KeypairUtil}; use std::error; -use std::fs::File; -use std::path::Path; /** * Bootstrap leader gets two tokens: @@ -23,6 +21,24 @@ pub const BOOTSTRAP_LEADER_TOKENS: u64 = 1_000_000; fn main() -> Result<(), Box> { let matches = App::new("solana-genesis") .version(crate_version!()) + .arg( + Arg::with_name("bootstrap_leader_keypair_file") + .short("b") + .long("bootstrap-leader-keypair") + .value_name("BOOTSTRAP LEADER KEYPAIR") + .takes_value(true) + .required(true) + .help("Path to file containing the bootstrap leader's keypair"), + ) + .arg( + Arg::with_name("ledger_path") + .short("l") + .long("ledger") + .value_name("DIR") + .takes_value(true) + .required(true) + .help("Use directory as persistent ledger location"), + ) .arg( Arg::with_name("num_tokens") .short("t") @@ -33,7 +49,7 @@ fn main() -> Result<(), Box> { .help("Number of tokens to create in the mint"), ) .arg( - Arg::with_name("mint") + Arg::with_name("mint_keypair_file") .short("m") .long("mint") .value_name("MINT") @@ -41,48 +57,23 @@ fn main() -> Result<(), Box> { .required(true) .help("Path to file containing keys of the mint"), ) - .arg( - Arg::with_name("bootstrap-leader-keypair") - .short("b") - .long("bootstrap-leader-keypair") - .value_name("BOOTSTRAP LEADER KEYPAIR") - .takes_value(true) - .required(true) - .help("Path to file containing the bootstrap leader's keypair"), - ) - .arg( - Arg::with_name("ledger") - .short("l") - .long("ledger") - .value_name("DIR") - .takes_value(true) - .required(true) - .help("Use directory as persistent ledger location"), - ) .get_matches(); - // Load the bootstreap leader keypair - // TODO: Only the public key is really needed, genesis should not have access to the leader's - // secret key. - let leader_keypair = read_keypair(matches.value_of("bootstrap-leader-keypair").unwrap()) - .expect("failed to read bootstrap leader keypair"); - - // Parse the input mint configuration + let bootstrap_leader_keypair_file = matches.value_of("bootstrap_leader_keypair_file").unwrap(); + let ledger_path = matches.value_of("ledger_path").unwrap(); + let mint_keypair_file = matches.value_of("mint_keypair_file").unwrap(); let num_tokens = value_t_or_exit!(matches, "num_tokens", u64); - let file = File::open(Path::new(&matches.value_of("mint").unwrap())).unwrap(); - let pkcs8: Vec = serde_json::from_reader(&file)?; - let mint = Mint::new_with_pkcs8( - num_tokens, - pkcs8, - leader_keypair.pubkey(), - BOOTSTRAP_LEADER_TOKENS, - ); - // Write the ledger entries - let entries = mint.create_entries(); + let bootstrap_leader_keypair = read_keypair(bootstrap_leader_keypair_file)?; + let mint_keypair = read_keypair(mint_keypair_file)?; - let ledger_path = matches.value_of("ledger").unwrap(); - genesis(&ledger_path, &leader_keypair, &entries)?; + let genesis_block = GenesisBlock { + mint_id: mint_keypair.pubkey(), + tokens: num_tokens, + bootstrap_leader_id: bootstrap_leader_keypair.pubkey(), + bootstrap_leader_tokens: BOOTSTRAP_LEADER_TOKENS, + }; + create_empty_ledger(ledger_path, &genesis_block)?; Ok(()) } diff --git a/ledger-tool/src/main.rs b/ledger-tool/src/main.rs index 1e0d8af07..1b870cf6c 100644 --- a/ledger-tool/src/main.rs +++ b/ledger-tool/src/main.rs @@ -1,6 +1,7 @@ use clap::{crate_version, App, Arg, SubCommand}; use solana::bank::Bank; use solana::db_ledger::DbLedger; +use solana::genesis_block::GenesisBlock; use std::io::{stdout, Write}; use std::process::exit; @@ -46,6 +47,14 @@ fn main() { let ledger_path = matches.value_of("ledger").unwrap(); + let genesis_block = GenesisBlock::load(ledger_path).unwrap_or_else(|err| { + eprintln!( + "Failed to open ledger genesis_block at {}: {}", + ledger_path, err + ); + exit(1); + }); + let db_ledger = match DbLedger::open(ledger_path) { Ok(db_ledger) => db_ledger, Err(err) => { @@ -54,7 +63,7 @@ fn main() { } }; - let mut entries = match db_ledger.read_ledger() { + let entries = match db_ledger.read_ledger() { Ok(entries) => entries, Err(err) => { eprintln!("Failed to read ledger at {}: {}", ledger_path, err); @@ -103,26 +112,7 @@ fn main() { stdout().write_all(b"\n]}\n").expect("close array"); } ("verify", _) => { - const NUM_GENESIS_ENTRIES: usize = 3; - if head < NUM_GENESIS_ENTRIES { - eprintln!( - "verify requires at least {} entries to run", - NUM_GENESIS_ENTRIES - ); - exit(1); - } - let bank = Bank::new_with_builtin_programs(); - { - let genesis = entries.by_ref().take(NUM_GENESIS_ENTRIES); - if let Err(e) = bank.process_ledger(genesis) { - eprintln!("verify failed at genesis err: {:?}", e); - if !matches.is_present("continue") { - exit(1); - } - } - } - let head = head - NUM_GENESIS_ENTRIES; - + let bank = Bank::new(&genesis_block); let mut last_id = bank.last_id(); let mut num_entries = 0; for (i, entry) in entries.enumerate() { diff --git a/src/bank.rs b/src/bank.rs index 6da5afad2..36ef5ee22 100644 --- a/src/bank.rs +++ b/src/bank.rs @@ -8,8 +8,8 @@ use crate::checkpoint::Checkpoint; use crate::counter::Counter; use crate::entry::Entry; use crate::entry::EntrySlice; +use crate::genesis_block::GenesisBlock; use crate::leader_scheduler::LeaderScheduler; -use crate::mint::Mint; use crate::poh_recorder::PohRecorder; use crate::runtime::{self, RuntimeError}; use crate::status_deque::{Status, StatusDeque, MAX_ENTRY_IDS}; @@ -24,12 +24,10 @@ use solana_sdk::bpf_loader; use solana_sdk::budget_program; use solana_sdk::hash::Hash; use solana_sdk::native_program::ProgramError; -use solana_sdk::payment_plan::Payment; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::Keypair; use solana_sdk::signature::Signature; use solana_sdk::storage_program; -use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_program; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::timing::duration_as_us; @@ -133,22 +131,9 @@ impl Default for Bank { } impl Bank { - /// Create an Bank with built-in programs. - pub fn new_with_builtin_programs() -> Self { + pub fn new(genesis_block: &GenesisBlock) -> Self { let bank = Self::default(); - bank.add_builtin_programs(); - bank - } - - /// Create an Bank using a deposit. - pub fn new_from_deposits(deposits: &[Payment]) -> Self { - let bank = Self::default(); - for deposit in deposits { - let mut account = Account::default(); - account.tokens += deposit.tokens; - - bank.accounts.store_slow(&deposit.to, &account); - } + bank.process_genesis_block(genesis_block); bank.add_builtin_programs(); bank } @@ -186,31 +171,26 @@ impl Bank { self.accounts.depth() } - /// Create an Bank with only a Mint. Typically used by unit tests. - pub fn new(mint: &Mint) -> Self { - let mint_tokens = if mint.bootstrap_leader_id != Pubkey::default() { - mint.tokens - mint.bootstrap_leader_tokens - } else { - mint.tokens + fn process_genesis_block(&self, genesis_block: &GenesisBlock) { + assert!(genesis_block.mint_id != Pubkey::default()); + assert!(genesis_block.tokens >= genesis_block.bootstrap_leader_tokens); + + let mut mint_account = Account::default(); + let mut bootstrap_leader_account = Account::default(); + mint_account.tokens += genesis_block.tokens; + + if genesis_block.bootstrap_leader_id != Pubkey::default() { + mint_account.tokens -= genesis_block.bootstrap_leader_tokens; + bootstrap_leader_account.tokens += genesis_block.bootstrap_leader_tokens; + self.accounts.store_slow( + &genesis_block.bootstrap_leader_id, + &bootstrap_leader_account, + ); }; - let mint_deposit = Payment { - to: mint.pubkey(), - tokens: mint_tokens, - }; - - let deposits = if mint.bootstrap_leader_id != Pubkey::default() { - let leader_deposit = Payment { - to: mint.bootstrap_leader_id, - tokens: mint.bootstrap_leader_tokens, - }; - vec![mint_deposit, leader_deposit] - } else { - vec![mint_deposit] - }; - let bank = Self::new_from_deposits(&deposits); - bank.register_tick(&mint.last_id()); - bank + self.accounts + .store_slow(&genesis_block.mint_id, &mint_account); + self.register_tick(&genesis_block.last_id()); } fn add_system_program(&self) { @@ -743,19 +723,14 @@ impl Bank { } /// Append entry blocks to the ledger, verifying them along the way. - fn process_ledger_blocks( - &self, - start_hash: Hash, - entry_height: u64, - entries: I, - ) -> Result<(u64, Hash)> + pub fn process_ledger(&self, entries: I) -> Result<(u64, Hash)> where I: IntoIterator, { // these magic numbers are from genesis of the mint, could pull them // back out of this loop. - let mut entry_height = entry_height; - let mut last_id = start_hash; + let mut entry_height = 0; + let mut last_id = self.last_id(); // Ledger verification needs to be parallelized, but we can't pull the whole // thing into memory. We therefore chunk it. @@ -775,96 +750,6 @@ impl Bank { Ok((entry_height, last_id)) } - /// Process a full ledger. - pub fn process_ledger(&self, entries: I) -> Result<(u64, Hash)> - where - I: IntoIterator, - { - let mut entries = entries.into_iter(); - - // The first item in the ledger is required to be an entry with zero num_hashes, - // which implies its id can be used as the ledger's seed. - let entry0 = entries.next().expect("invalid ledger: empty"); - - // The second item in the ledger consists of a transaction with - // two special instructions: - // 1) The first is a special move instruction where the to and from - // fields are the same. That entry should be treated as a deposit, not a - // transfer to oneself. - // 2) The second is a move instruction that acts as a payment to the first - // leader from the mint. This bootstrap leader will stay in power during the - // bootstrapping period of the network - let entry1 = entries - .next() - .expect("invalid ledger: need at least 2 entries"); - - // genesis should conform to PoH - assert!(entry1.verify(&entry0.id)); - - { - // Process the first transaction - let tx = &entry1.transactions[0]; - assert!(system_program::check_id(tx.program_id(0)), "Invalid ledger"); - assert!(system_program::check_id(tx.program_id(1)), "Invalid ledger"); - let mut instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap(); - let mint_deposit = if let SystemInstruction::Move { tokens } = instruction { - Some(tokens) - } else { - None - } - .expect("invalid ledger, needs to start with mint deposit"); - - instruction = deserialize(tx.userdata(1)).unwrap(); - let leader_payment = if let SystemInstruction::Move { tokens } = instruction { - Some(tokens) - } else { - None - } - .expect("invalid ledger, bootstrap leader payment expected"); - - assert!(leader_payment <= mint_deposit); - assert!(leader_payment > 0); - - { - // 1) Deposit into the mint - let mut account = self - .accounts - .load_slow(&tx.account_keys[0]) - .unwrap_or_default(); - account.tokens += mint_deposit - leader_payment; - self.accounts.store_slow(&tx.account_keys[0], &account); - trace!( - "applied genesis payment {:?} => {:?}", - mint_deposit - leader_payment, - account - ); - - // 2) Transfer tokens to the bootstrap leader. The first two - // account keys will both be the mint (because the mint is the source - // for this transaction and the first move instruction is to the - // mint itself), so we look at the third account key to find the first - // leader id. - let bootstrap_leader_id = tx.account_keys[2]; - let mut account = self - .accounts - .load_slow(&bootstrap_leader_id) - .unwrap_or_default(); - account.tokens += leader_payment; - self.accounts.store_slow(&bootstrap_leader_id, &account); - - self.leader_scheduler.write().unwrap().bootstrap_leader = bootstrap_leader_id; - - trace!( - "applied genesis payment to bootstrap leader {:?} => {:?}", - leader_payment, - account - ); - } - } - - Ok(self.process_ledger_blocks(entry1.id, 2, entries)?) - } - /// Create, sign, and process a Transaction from `keypair` to `to` of /// `n` tokens where `last_id` is the last Entry ID observed by the client. pub fn transfer( @@ -989,6 +874,7 @@ mod tests { use solana_sdk::signature::Keypair; use solana_sdk::signature::KeypairUtil; use solana_sdk::storage_program::{StorageTransaction, ENTRIES_PER_SEGMENT}; + use solana_sdk::system_instruction::SystemInstruction; use solana_sdk::system_transaction::SystemTransaction; use solana_sdk::transaction::Instruction; use std; @@ -996,33 +882,34 @@ mod tests { #[test] fn test_bank_new() { - let mint = Mint::new(10_000); - let bank = Bank::new(&mint); - assert_eq!(bank.get_balance(&mint.pubkey()), 10_000); + let (genesis_block, _) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); + assert_eq!(bank.get_balance(&genesis_block.mint_id), 10_000); } #[test] fn test_bank_new_with_leader() { let dummy_leader_id = Keypair::new().pubkey(); let dummy_leader_tokens = 1; - let mint = Mint::new_with_leader(10_000, dummy_leader_id, dummy_leader_tokens); - let bank = Bank::new(&mint); - assert_eq!(bank.get_balance(&mint.pubkey()), 9999); + let (genesis_block, _) = + GenesisBlock::new_with_leader(10_000, dummy_leader_id, dummy_leader_tokens); + let bank = Bank::new(&genesis_block); + assert_eq!(bank.get_balance(&genesis_block.mint_id), 9999); assert_eq!(bank.get_balance(&dummy_leader_id), 1); } #[test] fn test_two_payments_to_one_party() { - let mint = Mint::new(10_000); + let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); let pubkey = Keypair::new().pubkey(); - let bank = Bank::new(&mint); - assert_eq!(bank.last_id(), mint.last_id()); + let bank = Bank::new(&genesis_block); + assert_eq!(bank.last_id(), genesis_block.last_id()); - bank.transfer(1_000, &mint.keypair(), pubkey, mint.last_id()) + bank.transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&pubkey), 1_000); - bank.transfer(500, &mint.keypair(), pubkey, mint.last_id()) + bank.transfer(500, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&pubkey), 1_500); assert_eq!(bank.transaction_count(), 2); @@ -1030,19 +917,19 @@ mod tests { #[test] fn test_one_source_two_tx_one_batch() { - let mint = Mint::new(1); + let (genesis_block, mint_keypair) = GenesisBlock::new(1); let key1 = Keypair::new().pubkey(); let key2 = Keypair::new().pubkey(); - let bank = Bank::new(&mint); - assert_eq!(bank.last_id(), mint.last_id()); + let bank = Bank::new(&genesis_block); + assert_eq!(bank.last_id(), genesis_block.last_id()); - let t1 = Transaction::system_move(&mint.keypair(), key1, 1, mint.last_id(), 0); - let t2 = Transaction::system_move(&mint.keypair(), key2, 1, mint.last_id(), 0); + let t1 = Transaction::system_move(&mint_keypair, key1, 1, genesis_block.last_id(), 0); + let t2 = Transaction::system_move(&mint_keypair, key2, 1, genesis_block.last_id(), 0); let res = bank.process_transactions(&vec![t1.clone(), t2.clone()]); assert_eq!(res.len(), 2); assert_eq!(res[0], Ok(())); assert_eq!(res[1], Err(BankError::AccountInUse)); - assert_eq!(bank.get_balance(&mint.pubkey()), 0); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0); assert_eq!(bank.get_balance(&key1), 1); assert_eq!(bank.get_balance(&key2), 0); assert_eq!( @@ -1058,10 +945,10 @@ mod tests { #[test] fn test_one_tx_two_out_atomic_fail() { - let mint = Mint::new(1); + let (genesis_block, mint_keypair) = GenesisBlock::new(1); let key1 = Keypair::new().pubkey(); let key2 = Keypair::new().pubkey(); - let bank = Bank::new(&mint); + let bank = Bank::new(&genesis_block); let spend = SystemInstruction::Move { tokens: 1 }; let instructions = vec![ Instruction { @@ -1077,9 +964,9 @@ mod tests { ]; let t1 = Transaction::new_with_instructions( - &[&mint.keypair()], + &[&mint_keypair], &[key1, key2], - mint.last_id(), + genesis_block.last_id(), 0, vec![system_program::id()], instructions, @@ -1093,7 +980,7 @@ mod tests { ProgramError::ResultWithNegativeTokens )) ); - assert_eq!(bank.get_balance(&mint.pubkey()), 1); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1); assert_eq!(bank.get_balance(&key1), 0); assert_eq!(bank.get_balance(&key2), 0); assert_eq!( @@ -1107,20 +994,20 @@ mod tests { #[test] fn test_one_tx_two_out_atomic_pass() { - let mint = Mint::new(2); + let (genesis_block, mint_keypair) = GenesisBlock::new(2); let key1 = Keypair::new().pubkey(); let key2 = Keypair::new().pubkey(); - let bank = Bank::new(&mint); + let bank = Bank::new(&genesis_block); let t1 = Transaction::system_move_many( - &mint.keypair(), + &mint_keypair, &[(key1, 1), (key2, 1)], - mint.last_id(), + genesis_block.last_id(), 0, ); let res = bank.process_transactions(&vec![t1.clone()]); assert_eq!(res.len(), 1); assert_eq!(res[0], Ok(())); - assert_eq!(bank.get_balance(&mint.pubkey()), 0); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0); assert_eq!(bank.get_balance(&key1), 1); assert_eq!(bank.get_balance(&key2), 1); assert_eq!( @@ -1133,15 +1020,15 @@ mod tests { // See github issue 1157 (https://github.com/solana-labs/solana/issues/1157) #[test] fn test_detect_failed_duplicate_transactions_issue_1157() { - let mint = Mint::new(1); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let bank = Bank::new(&genesis_block); let dest = Keypair::new(); // source with 0 program context let tx = Transaction::system_create( - &mint.keypair(), + &mint_keypair, dest.pubkey(), - mint.last_id(), + genesis_block.last_id(), 2, 0, Pubkey::default(), @@ -1166,16 +1053,16 @@ mod tests { assert_eq!(bank.get_balance(&dest.pubkey()), 0); // BUG: This should be the original balance minus the transaction fee. - //assert_eq!(bank.get_balance(&mint.pubkey()), 0); + //assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 0); } #[test] fn test_account_not_found() { - let mint = Mint::new(1); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); assert_eq!( - bank.transfer(1, &keypair, mint.pubkey(), mint.last_id()), + bank.transfer(1, &keypair, mint_keypair.pubkey(), genesis_block.last_id()), Err(BankError::AccountNotFound) ); assert_eq!(bank.transaction_count(), 0); @@ -1183,15 +1070,15 @@ mod tests { #[test] fn test_insufficient_funds() { - let mint = Mint::new(11_000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(11_000); + let bank = Bank::new(&genesis_block); let pubkey = Keypair::new().pubkey(); - bank.transfer(1_000, &mint.keypair(), pubkey, mint.last_id()) + bank.transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_eq!(bank.transaction_count(), 1); assert_eq!(bank.get_balance(&pubkey), 1_000); assert_matches!( - bank.transfer(10_001, &mint.keypair(), pubkey, mint.last_id()), + bank.transfer(10_001, &mint_keypair, pubkey, genesis_block.last_id()), Err(BankError::ProgramError( 0, ProgramError::ResultWithNegativeTokens @@ -1199,28 +1086,30 @@ mod tests { ); assert_eq!(bank.transaction_count(), 1); - let mint_pubkey = mint.keypair().pubkey(); + let mint_pubkey = mint_keypair.pubkey(); assert_eq!(bank.get_balance(&mint_pubkey), 10_000); assert_eq!(bank.get_balance(&pubkey), 1_000); } #[test] fn test_transfer_to_newb() { - let mint = Mint::new(10_000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let pubkey = Keypair::new().pubkey(); - bank.transfer(500, &mint.keypair(), pubkey, mint.last_id()) + bank.transfer(500, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&pubkey), 500); } #[test] fn test_debits_before_credits() { - let mint = Mint::new(2); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); - let tx0 = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 2, mint.last_id()); - let tx1 = Transaction::system_new(&keypair, mint.pubkey(), 1, mint.last_id()); + let tx0 = + Transaction::system_new(&mint_keypair, keypair.pubkey(), 2, genesis_block.last_id()); + let tx1 = + Transaction::system_new(&keypair, mint_keypair.pubkey(), 1, genesis_block.last_id()); let txs = vec![tx0, tx1]; let results = bank.process_transactions(&txs); assert!(results[1].is_err()); @@ -1231,11 +1120,11 @@ mod tests { #[test] fn test_process_empty_entry_is_registered() { - let mint = Mint::new(1); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1); + let bank = Bank::new(&genesis_block); let keypair = Keypair::new(); - let entry = next_entry(&mint.last_id(), 1, vec![]); - let tx = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 1, entry.id); + let entry = next_entry(&genesis_block.last_id(), 1, vec![]); + let tx = Transaction::system_new(&mint_keypair, keypair.pubkey(), 1, entry.id); // First, ensure the TX is rejected because of the unregistered last ID assert_eq!( @@ -1252,29 +1141,34 @@ mod tests { fn test_process_genesis() { let dummy_leader_id = Keypair::new().pubkey(); let dummy_leader_tokens = 1; - let mint = Mint::new_with_leader(5, dummy_leader_id, dummy_leader_tokens); - let genesis = mint.create_entries(); + let (genesis_block, _) = + GenesisBlock::new_with_leader(5, dummy_leader_id, dummy_leader_tokens); let bank = Bank::default(); - bank.process_ledger(genesis).unwrap(); - assert_eq!(bank.get_balance(&mint.pubkey()), 4); + bank.process_genesis_block(&genesis_block); + assert_eq!(bank.get_balance(&genesis_block.mint_id), 4); assert_eq!(bank.get_balance(&dummy_leader_id), 1); + // TODO: Restore next assert_eq() once leader scheduler configuration is stored in the + // genesis block + /* assert_eq!( bank.leader_scheduler.read().unwrap().bootstrap_leader, dummy_leader_id ); + */ } fn create_sample_block_with_next_entries_using_keypairs( - mint: &Mint, + genesis_block: &GenesisBlock, + mint_keypair: &Keypair, keypairs: &[Keypair], ) -> impl Iterator { - let mut last_id = mint.last_id(); - let mut hash = mint.last_id(); + let mut last_id = genesis_block.last_id(); + let mut hash = genesis_block.last_id(); let mut entries: Vec = vec![]; let num_hashes = 1; for k in keypairs { let txs = vec![Transaction::system_new( - &mint.keypair(), + mint_keypair, k.pubkey(), 1, last_id, @@ -1292,17 +1186,18 @@ mod tests { // create a ledger with tick entries every `ticks` entries fn create_sample_block_with_ticks( - mint: &Mint, + genesis_block: &GenesisBlock, + mint_keypair: &Keypair, length: usize, ticks: usize, ) -> impl Iterator { let mut entries = Vec::with_capacity(length); - let mut hash = mint.last_id(); - let mut last_id = mint.last_id(); + let mut last_id = genesis_block.last_id(); + let mut hash = genesis_block.last_id(); let num_hashes = 1; for i in 0..length { let keypair = Keypair::new(); - let tx = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 1, last_id); + let tx = Transaction::system_new(mint_keypair, keypair.pubkey(), 1, last_id); let entry = Entry::new(&hash, 0, num_hashes, vec![tx]); hash = entry.id; entries.push(entry); @@ -1325,57 +1220,61 @@ mod tests { entries.into_iter() } - fn create_sample_ledger(length: usize) -> (impl Iterator, Pubkey) { - let dummy_leader_id = Keypair::new().pubkey(); - let dummy_leader_tokens = 1; - let mint = Mint::new_with_leader( - length as u64 + 1 + dummy_leader_tokens, - dummy_leader_id, - dummy_leader_tokens, - ); - let genesis = mint.create_entries(); - let block = create_sample_block_with_ticks(&mint, length, length); - (genesis.into_iter().chain(block), mint.pubkey()) - } - - fn create_sample_ledger_with_mint_and_keypairs( - mint: &Mint, - keypairs: &[Keypair], - ) -> impl Iterator { - let genesis = mint.create_entries(); - let block = create_sample_block_with_next_entries_using_keypairs(mint, keypairs); - genesis.into_iter().chain(block) + fn create_sample_ledger(length: usize) -> (GenesisBlock, Keypair, impl Iterator) { + let mint_keypair = Keypair::new(); + let genesis_block = GenesisBlock { + bootstrap_leader_id: Keypair::new().pubkey(), + bootstrap_leader_tokens: 1, + mint_id: mint_keypair.pubkey(), + tokens: length as u64 + 2, + }; + let block = create_sample_block_with_ticks(&genesis_block, &mint_keypair, length, length); + (genesis_block, mint_keypair, block) } #[test] fn test_process_ledger_simple() { - let (ledger, pubkey) = create_sample_ledger(1); + let (genesis_block, mint_keypair, ledger) = create_sample_ledger(1); let bank = Bank::default(); + bank.process_genesis_block(&genesis_block); bank.add_system_program(); let (ledger_height, last_id) = bank.process_ledger(ledger).unwrap(); - assert_eq!(bank.get_balance(&pubkey), 1); - assert_eq!(ledger_height, 6); + assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1); + assert_eq!(ledger_height, 3); assert_eq!(bank.tick_height(), 2); assert_eq!(bank.last_id(), last_id); } #[test] fn test_hash_internal_state() { - let dummy_leader_id = Keypair::new().pubkey(); - let dummy_leader_tokens = 1; - let mint = Mint::new_with_leader(2_000, dummy_leader_id, dummy_leader_tokens); - + let mint_keypair = Keypair::new(); + let genesis_block = GenesisBlock { + bootstrap_leader_id: Keypair::new().pubkey(), + bootstrap_leader_tokens: 1, + mint_id: mint_keypair.pubkey(), + tokens: 2_000, + }; let seed = [0u8; 32]; let mut rnd = GenKeys::new(seed); let keypairs = rnd.gen_n_keypairs(5); - let ledger0 = create_sample_ledger_with_mint_and_keypairs(&mint, &keypairs); - let ledger1 = create_sample_ledger_with_mint_and_keypairs(&mint, &keypairs); + let ledger0 = create_sample_block_with_next_entries_using_keypairs( + &genesis_block, + &mint_keypair, + &keypairs, + ); + let ledger1 = create_sample_block_with_next_entries_using_keypairs( + &genesis_block, + &mint_keypair, + &keypairs, + ); let bank0 = Bank::default(); bank0.add_system_program(); + bank0.process_genesis_block(&genesis_block); bank0.process_ledger(ledger0).unwrap(); let bank1 = Bank::default(); bank1.add_system_program(); + bank1.process_genesis_block(&genesis_block); bank1.process_ledger(ledger1).unwrap(); let initial_state = bank0.hash_internal_state(); @@ -1384,11 +1283,11 @@ mod tests { let pubkey = keypairs[0].pubkey(); bank0 - .transfer(1_000, &mint.keypair(), pubkey, mint.last_id()) + .transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_ne!(bank0.hash_internal_state(), initial_state); bank1 - .transfer(1_000, &mint.keypair(), pubkey, mint.last_id()) + .transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id()) .unwrap(); assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state()); } @@ -1401,12 +1300,13 @@ mod tests { } #[test] fn test_interleaving_locks() { - let mint = Mint::new(3); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(3); + let bank = Bank::new(&genesis_block); let alice = Keypair::new(); let bob = Keypair::new(); - let tx1 = Transaction::system_new(&mint.keypair(), alice.pubkey(), 1, mint.last_id()); + let tx1 = + Transaction::system_new(&mint_keypair, alice.pubkey(), 1, genesis_block.last_id()); let pay_alice = vec![tx1]; let lock_result = bank.lock_accounts(&pay_alice); @@ -1416,20 +1316,20 @@ mod tests { // try executing an interleaved transfer twice assert_eq!( - bank.transfer(1, &mint.keypair(), bob.pubkey(), mint.last_id()), + bank.transfer(1, &mint_keypair, bob.pubkey(), genesis_block.last_id()), Err(BankError::AccountInUse) ); // the second time should fail as well // this verifies that `unlock_accounts` doesn't unlock `AccountInUse` accounts assert_eq!( - bank.transfer(1, &mint.keypair(), bob.pubkey(), mint.last_id()), + bank.transfer(1, &mint_keypair, bob.pubkey(), genesis_block.last_id()), Err(BankError::AccountInUse) ); bank.unlock_accounts(&pay_alice, &results_alice); assert_matches!( - bank.transfer(2, &mint.keypair(), bob.pubkey(), mint.last_id()), + bank.transfer(2, &mint_keypair, bob.pubkey(), genesis_block.last_id()), Ok(_) ); } @@ -1468,27 +1368,27 @@ mod tests { } #[test] fn test_par_process_entries_tick() { - let mint = Mint::new(1000); - let bank = Bank::new(&mint); + let (genesis_block, _mint_keypair) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); // ensure bank can process a tick - let tick = next_entry(&mint.last_id(), 1, vec![]); + let tick = next_entry(&genesis_block.last_id(), 1, vec![]); assert_eq!(bank.par_process_entries(&[tick.clone()]), Ok(())); assert_eq!(bank.last_id(), tick.id); } #[test] fn test_par_process_entries_2_entries_collision() { - let mint = Mint::new(1000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); let last_id = bank.last_id(); // ensure bank can process 2 entries that have a common account and no tick is registered - let tx = Transaction::system_new(&mint.keypair(), keypair1.pubkey(), 2, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair1.pubkey(), 2, bank.last_id()); let entry_1 = next_entry(&last_id, 1, vec![tx]); - let tx = Transaction::system_new(&mint.keypair(), keypair2.pubkey(), 2, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair2.pubkey(), 2, bank.last_id()); let entry_2 = next_entry(&entry_1.id, 1, vec![tx]); assert_eq!(bank.par_process_entries(&[entry_1, entry_2]), Ok(())); assert_eq!(bank.get_balance(&keypair1.pubkey()), 2); @@ -1497,23 +1397,23 @@ mod tests { } #[test] fn test_par_process_entries_2_txes_collision() { - let mint = Mint::new(1000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); let keypair3 = Keypair::new(); println!("KP1 {:?}", keypair1.pubkey()); println!("KP2 {:?}", keypair2.pubkey()); println!("KP3 {:?}", keypair3.pubkey()); - println!("Mint {:?}", mint.keypair().pubkey()); + println!("GenesisBlock {:?}", mint_keypair.pubkey()); // fund: put 4 in each of 1 and 2 assert_matches!( - bank.transfer(4, &mint.keypair(), keypair1.pubkey(), bank.last_id()), + bank.transfer(4, &mint_keypair, keypair1.pubkey(), bank.last_id()), Ok(_) ); assert_matches!( - bank.transfer(4, &mint.keypair(), keypair2.pubkey(), bank.last_id()), + bank.transfer(4, &mint_keypair, keypair2.pubkey(), bank.last_id()), Ok(_) ); @@ -1523,7 +1423,7 @@ mod tests { 1, vec![Transaction::system_new( &keypair1, - mint.keypair().pubkey(), + mint_keypair.pubkey(), 1, bank.last_id(), )], @@ -1534,7 +1434,7 @@ mod tests { 1, vec![ Transaction::system_new(&keypair2, keypair3.pubkey(), 2, bank.last_id()), // should be fine - Transaction::system_new(&keypair1, mint.keypair().pubkey(), 2, bank.last_id()), // will collide + Transaction::system_new(&keypair1, mint_keypair.pubkey(), 2, bank.last_id()), // will collide ], ); @@ -1549,17 +1449,17 @@ mod tests { } #[test] fn test_par_process_entries_2_entries_par() { - let mint = Mint::new(1000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); let keypair3 = Keypair::new(); let keypair4 = Keypair::new(); //load accounts - let tx = Transaction::system_new(&mint.keypair(), keypair1.pubkey(), 1, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair1.pubkey(), 1, bank.last_id()); assert_eq!(bank.process_transaction(&tx), Ok(())); - let tx = Transaction::system_new(&mint.keypair(), keypair2.pubkey(), 1, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair2.pubkey(), 1, bank.last_id()); assert_eq!(bank.process_transaction(&tx), Ok(())); // ensure bank can process 2 entries that do not have a common account and no tick is registered @@ -1575,17 +1475,17 @@ mod tests { } #[test] fn test_par_process_entries_2_entries_tick() { - let mint = Mint::new(1000); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); let keypair1 = Keypair::new(); let keypair2 = Keypair::new(); let keypair3 = Keypair::new(); let keypair4 = Keypair::new(); //load accounts - let tx = Transaction::system_new(&mint.keypair(), keypair1.pubkey(), 1, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair1.pubkey(), 1, bank.last_id()); assert_eq!(bank.process_transaction(&tx), Ok(())); - let tx = Transaction::system_new(&mint.keypair(), keypair2.pubkey(), 1, bank.last_id()); + let tx = Transaction::system_new(&mint_keypair, keypair2.pubkey(), 1, bank.last_id()); assert_eq!(bank.process_transaction(&tx), Ok(())); let last_id = bank.last_id(); @@ -1673,17 +1573,17 @@ mod tests { #[test] fn test_bank_purge() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let bob = Keypair::new(); let charlie = Keypair::new(); // bob should have 500 - bank.transfer(500, &alice.keypair(), bob.pubkey(), alice.last_id()) + bank.transfer(500, &alice, bob.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&bob.pubkey()), 500); - bank.transfer(500, &alice.keypair(), charlie.pubkey(), alice.last_id()) + bank.transfer(500, &alice, charlie.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&charlie.pubkey()), 500); @@ -1696,7 +1596,7 @@ mod tests { assert_eq!(bank.transaction_count(), 2); // transfer money back, so bob has zero - bank.transfer(500, &bob, alice.keypair().pubkey(), alice.last_id()) + bank.transfer(500, &bob, alice.pubkey(), genesis_block.last_id()) .unwrap(); // this has to be stored as zero in the top accounts hashmap ;) assert!(bank.accounts.load_slow(&bob.pubkey()).is_some()); @@ -1728,13 +1628,13 @@ mod tests { #[test] fn test_bank_checkpoint_zero_balance() { - let alice = Mint::new(1_000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(1_000); + let bank = Bank::new(&genesis_block); let bob = Keypair::new(); let charlie = Keypair::new(); // bob should have 500 - bank.transfer(500, &alice.keypair(), bob.pubkey(), alice.last_id()) + bank.transfer(500, &alice, bob.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&bob.pubkey()), 500); assert_eq!(bank.checkpoint_depth(), 0); @@ -1750,7 +1650,7 @@ mod tests { assert_eq!(bank.checkpoint_depth(), 1); // charlie should have 500, alice should have 0 - bank.transfer(500, &alice.keypair(), charlie.pubkey(), alice.last_id()) + bank.transfer(500, &alice, charlie.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&charlie.pubkey()), 500); assert_eq!(bank.get_balance(&alice.pubkey()), 0); @@ -1774,16 +1674,16 @@ mod tests { #[test] fn test_bank_checkpoint_rollback() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let bob = Keypair::new(); let charlie = Keypair::new(); // bob should have 500 - bank.transfer(500, &alice.keypair(), bob.pubkey(), alice.last_id()) + bank.transfer(500, &alice, bob.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&bob.pubkey()), 500); - bank.transfer(500, &alice.keypair(), charlie.pubkey(), alice.last_id()) + bank.transfer(500, &alice, charlie.pubkey(), genesis_block.last_id()) .unwrap(); assert_eq!(bank.get_balance(&charlie.pubkey()), 500); assert_eq!(bank.checkpoint_depth(), 0); @@ -1796,7 +1696,7 @@ mod tests { assert_eq!(bank.transaction_count(), 2); // transfer money back, so bob has zero - bank.transfer(500, &bob, alice.keypair().pubkey(), alice.last_id()) + bank.transfer(500, &bob, alice.pubkey(), genesis_block.last_id()) .unwrap(); // this has to be stored as zero in the top accounts hashmap ;) assert_eq!(bank.get_balance(&bob.pubkey()), 0); @@ -1817,18 +1717,18 @@ mod tests { } assert_eq!(bank.tick_height(), MAX_ENTRY_IDS as u64 + 2); assert_eq!( - reserve_signature_with_last_id_test(&bank, &signature, &alice.last_id()), + reserve_signature_with_last_id_test(&bank, &signature, &genesis_block.last_id()), Err(StatusDequeError::LastIdNotFound) ); bank.rollback(); assert_eq!(bank.tick_height(), 1); assert_eq!( - reserve_signature_with_last_id_test(&bank, &signature, &alice.last_id()), + reserve_signature_with_last_id_test(&bank, &signature, &genesis_block.last_id()), Ok(()) ); bank.checkpoint(); assert_eq!( - reserve_signature_with_last_id_test(&bank, &signature, &alice.last_id()), + reserve_signature_with_last_id_test(&bank, &signature, &genesis_block.last_id()), Err(StatusDequeError::DuplicateSignature) ); } @@ -1836,22 +1736,22 @@ mod tests { #[test] #[should_panic] fn test_bank_rollback_panic() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, _) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); bank.rollback(); } #[test] fn test_bank_record_transactions() { - let mint = Mint::new(10_000); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let bank = Arc::new(Bank::new(&genesis_block)); let (entry_sender, entry_receiver) = channel(); let poh_recorder = PohRecorder::new(bank.clone(), entry_sender, bank.last_id(), None); let pubkey = Keypair::new().pubkey(); let transactions = vec![ - Transaction::system_move(&mint.keypair(), pubkey, 1, mint.last_id(), 0), - Transaction::system_move(&mint.keypair(), pubkey, 1, mint.last_id(), 0), + Transaction::system_move(&mint_keypair, pubkey, 1, genesis_block.last_id(), 0), + Transaction::system_move(&mint_keypair, pubkey, 1, genesis_block.last_id(), 0), ]; let mut results = vec![Ok(()), Ok(())]; @@ -1904,8 +1804,8 @@ mod tests { #[test] fn test_bank_storage() { solana_logger::setup(); - let alice = Mint::new(1000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(1000); + let bank = Bank::new(&genesis_block); let bob = Keypair::new(); let jack = Keypair::new(); @@ -1918,13 +1818,10 @@ mod tests { bank.register_tick(&last_id); - bank.transfer(10, &alice.keypair(), jill.pubkey(), last_id) - .unwrap(); + bank.transfer(10, &alice, jill.pubkey(), last_id).unwrap(); - bank.transfer(10, &alice.keypair(), bob.pubkey(), last_id) - .unwrap(); - bank.transfer(10, &alice.keypair(), jack.pubkey(), last_id) - .unwrap(); + bank.transfer(10, &alice, bob.pubkey(), last_id).unwrap(); + bank.transfer(10, &alice, jack.pubkey(), last_id).unwrap(); let tx = Transaction::storage_new_advertise_last_id( &bob, @@ -1954,15 +1851,15 @@ mod tests { #[test] fn test_bank_process_and_record_transactions() { - let mint = Mint::new(10_000); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let bank = Arc::new(Bank::new(&genesis_block)); let pubkey = Keypair::new().pubkey(); let transactions = vec![Transaction::system_move( - &mint.keypair(), + &mint_keypair, pubkey, 1, - mint.last_id(), + genesis_block.last_id(), 0, )]; @@ -1993,10 +1890,10 @@ mod tests { } let transactions = vec![Transaction::system_move( - &mint.keypair(), + &mint_keypair, pubkey, 2, - mint.last_id(), + genesis_block.last_id(), 0, )]; diff --git a/src/banking_stage.rs b/src/banking_stage.rs index 3ad63e8d0..f9822b6c1 100644 --- a/src/banking_stage.rs +++ b/src/banking_stage.rs @@ -269,7 +269,7 @@ mod tests { use crate::bank::Bank; use crate::banking_stage::BankingStageReturnType; use crate::entry::EntrySlice; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use crate::packet::to_packets; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; @@ -278,7 +278,8 @@ mod tests { #[test] fn test_banking_stage_shutdown1() { - let bank = Arc::new(Bank::new(&Mint::new(2))); + let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, _entry_receiver) = BankingStage::new( @@ -298,7 +299,8 @@ mod tests { #[test] fn test_banking_stage_shutdown2() { - let bank = Arc::new(Bank::new(&Mint::new(2))); + let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let (_verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( @@ -318,7 +320,8 @@ mod tests { #[test] fn test_banking_stage_tick() { - let bank = Arc::new(Bank::new(&Mint::new(2))); + let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let start_hash = bank.last_id(); let (verified_sender, verified_receiver) = channel(); @@ -345,8 +348,8 @@ mod tests { #[test] fn test_banking_stage_entries_only() { - let mint = Mint::new(2); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let start_hash = bank.last_id(); let (verified_sender, verified_receiver) = channel(); @@ -360,7 +363,7 @@ mod tests { ); // good tx - let keypair = mint.keypair(); + let keypair = mint_keypair; let tx = Transaction::system_new(&keypair, keypair.pubkey(), 1, start_hash); // good tx, but no verify @@ -402,8 +405,8 @@ 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 mint = Mint::new(2); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let (verified_sender, verified_receiver) = channel(); let (banking_stage, entry_receiver) = BankingStage::new( @@ -417,7 +420,7 @@ mod tests { // Process a batch that includes a transaction that receives two tokens. let alice = Keypair::new(); - let tx = Transaction::system_new(&mint.keypair(), alice.pubkey(), 2, mint.last_id()); + let tx = Transaction::system_new(&mint_keypair, alice.pubkey(), 2, genesis_block.last_id()); let packets = to_packets(&[tx]); verified_sender @@ -425,7 +428,7 @@ mod tests { .unwrap(); // Process a second batch that spends one of those tokens. - let tx = Transaction::system_new(&alice, mint.pubkey(), 1, mint.last_id()); + let tx = Transaction::system_new(&alice, mint_keypair.pubkey(), 1, genesis_block.last_id()); let packets = to_packets(&[tx]); verified_sender .send(vec![(packets[0].clone(), vec![1u8])]) @@ -444,7 +447,7 @@ mod tests { // Assert the user holds one token, not two. If the stage only outputs one // entry, then the second transaction will be rejected, because it drives // the account balance below zero before the credit is added. - let bank = Bank::new(&mint); + let bank = Bank::new(&genesis_block); for entry in entries { bank.process_transactions(&entry.transactions) .iter() @@ -457,7 +460,8 @@ mod tests { // with reason BankingStageReturnType::LeaderRotation #[test] fn test_max_tick_height_shutdown() { - let bank = Arc::new(Bank::new(&Mint::new(2))); + let (genesis_block, _mint_keypair) = GenesisBlock::new(2); + let bank = Arc::new(Bank::new(&genesis_block)); let dummy_leader_id = Keypair::new().pubkey(); let (_verified_sender_, verified_receiver) = channel(); let max_tick_height = 10; diff --git a/src/compute_leader_confirmation_service.rs b/src/compute_leader_confirmation_service.rs index 73d8b66ca..7e094a81d 100644 --- a/src/compute_leader_confirmation_service.rs +++ b/src/compute_leader_confirmation_service.rs @@ -161,7 +161,7 @@ pub mod tests { use crate::compute_leader_confirmation_service::ComputeLeaderConfirmationService; use crate::vote_signer_proxy::VoteSignerProxy; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use bincode::serialize; use solana_sdk::hash::hash; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -174,9 +174,9 @@ pub mod tests { fn test_compute_confirmation() { solana_logger::setup(); - let mint = Mint::new(1234); + let (genesis_block, mint_keypair) = GenesisBlock::new(1234); let dummy_leader_id = Keypair::new().pubkey(); - let bank = Arc::new(Bank::new(&mint)); + let bank = Arc::new(Bank::new(&genesis_block)); // generate 10 validators, but only vote for the first 6 validators let ids: Vec<_> = (0..10) .map(|i| { @@ -199,7 +199,7 @@ pub mod tests { VoteSignerProxy::new(&validator_keypair, Box::new(LocalVoteSigner::default())); // Give the validator some tokens - bank.transfer(2, &mint.keypair(), validator_keypair.pubkey(), last_id) + bank.transfer(2, &mint_keypair, validator_keypair.pubkey(), last_id) .unwrap(); vote_signer .new_vote_account(&bank, 1, last_id) diff --git a/src/db_ledger.rs b/src/db_ledger.rs index dd44e6e8d..e3ff089d2 100644 --- a/src/db_ledger.rs +++ b/src/db_ledger.rs @@ -2,9 +2,8 @@ //! Proof of History ledger as well as iterative read, append write, and random //! access read to a persistent file-based ledger. -use crate::entry::create_ticks; use crate::entry::Entry; -use crate::mint::Mint; +use crate::genesis_block::GenesisBlock; use crate::packet::{Blob, SharedBlob, BLOB_HEADER_SIZE}; use crate::result::{Error, Result}; use bincode::{deserialize, serialize}; @@ -17,7 +16,7 @@ use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use std::borrow::Borrow; use std::cmp; -use std::fs::{create_dir_all, remove_dir_all}; +use std::fs; use std::io; use std::path::Path; use std::sync::Arc; @@ -298,7 +297,7 @@ pub const ERASURE_CF: &str = "erasure"; impl DbLedger { // Opens a Ledger in directory, provides "infinite" window of blobs pub fn open(ledger_path: &str) -> Result { - create_dir_all(&ledger_path)?; + fs::create_dir_all(&ledger_path)?; let ledger_path = Path::new(ledger_path).join(DB_LEDGER_DIRECTORY); // Use default database options @@ -340,7 +339,7 @@ impl DbLedger { pub fn destroy(ledger_path: &str) -> Result<()> { // DB::destroy() fails if `ledger_path` doesn't exist - create_dir_all(&ledger_path)?; + fs::create_dir_all(&ledger_path)?; let ledger_path = Path::new(ledger_path).join(DB_LEDGER_DIRECTORY); DB::destroy(&Options::default(), &ledger_path)?; Ok(()) @@ -831,6 +830,13 @@ impl Iterator for EntryIterator { } } +pub fn create_empty_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Result<()> { + DbLedger::destroy(ledger_path)?; + DbLedger::open(ledger_path)?; + genesis_block.write(&ledger_path)?; + Ok(()) +} + pub fn genesis<'a, I>(ledger_path: &str, keypair: &Keypair, entries: I) -> Result<()> where I: IntoIterator, @@ -862,20 +868,15 @@ pub fn get_tmp_ledger_path(name: &str) -> String { let path = format!("{}/tmp/ledger-{}-{}", out_dir, name, keypair.pubkey()); // whack any possible collision - let _ignored = remove_dir_all(&path); + let _ignored = fs::remove_dir_all(&path); path } -pub fn create_tmp_ledger_with_mint(name: &str, mint: &Mint) -> String { - let path = get_tmp_ledger_path(name); - DbLedger::destroy(&path).expect("Expected successful database destruction"); - let db_ledger = DbLedger::open(&path).unwrap(); - db_ledger - .write_entries(DEFAULT_SLOT_HEIGHT, 0, &mint.create_entries()) - .unwrap(); - - path +pub fn create_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> String { + let ledger_path = get_tmp_ledger_path(name); + create_empty_ledger(&ledger_path, genesis_block).unwrap(); + ledger_path } pub fn create_tmp_genesis( @@ -883,11 +884,12 @@ pub fn create_tmp_genesis( num: u64, bootstrap_leader_id: Pubkey, bootstrap_leader_tokens: u64, -) -> (Mint, String) { - let mint = Mint::new_with_leader(num, bootstrap_leader_id, bootstrap_leader_tokens); - let path = create_tmp_ledger_with_mint(name, &mint); +) -> (GenesisBlock, Keypair, String) { + let (genesis_block, mint_keypair) = + GenesisBlock::new_with_leader(num, bootstrap_leader_id, bootstrap_leader_tokens); + let ledger_path = create_tmp_ledger(name, &genesis_block); - (mint, path) + (genesis_block, mint_keypair, ledger_path) } pub fn create_tmp_sample_ledger( @@ -896,37 +898,36 @@ pub fn create_tmp_sample_ledger( num_ending_ticks: usize, bootstrap_leader_id: Pubkey, bootstrap_leader_tokens: u64, -) -> (Mint, String, Vec) { - let mint = Mint::new_with_leader(num_tokens, bootstrap_leader_id, bootstrap_leader_tokens); +) -> (GenesisBlock, Keypair, String, Vec) { + let (genesis_block, mint_keypair) = + GenesisBlock::new_with_leader(num_tokens, bootstrap_leader_id, bootstrap_leader_tokens); + let path = get_tmp_ledger_path(name); + create_empty_ledger(&path, &genesis_block).unwrap(); + + let entries = crate::entry::create_ticks(num_ending_ticks, genesis_block.last_id()); + + let db_ledger = DbLedger::open(&path).unwrap(); + db_ledger + .write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries) + .unwrap(); + (genesis_block, mint_keypair, path, entries) +} + +pub fn tmp_copy_ledger(from: &str, name: &str) -> String { let path = get_tmp_ledger_path(name); - // Create the entries - let mut genesis = mint.create_entries(); - let ticks = create_ticks(num_ending_ticks, mint.last_id()); - genesis.extend(ticks); + let db_ledger = DbLedger::open(from).unwrap(); + let ledger_entries = db_ledger.read_ledger().unwrap(); + let genesis_block = GenesisBlock::load(from).unwrap(); DbLedger::destroy(&path).expect("Expected successful database destruction"); let db_ledger = DbLedger::open(&path).unwrap(); - db_ledger - .write_entries(DEFAULT_SLOT_HEIGHT, 0, &genesis) - .unwrap(); - - (mint, path, genesis) -} - -pub fn tmp_copy_ledger(from: &str, name: &str) -> String { - let tostr = get_tmp_ledger_path(name); - - let db_ledger = DbLedger::open(from).unwrap(); - let ledger_entries = db_ledger.read_ledger().unwrap(); - - DbLedger::destroy(&tostr).expect("Expected successful database destruction"); - let db_ledger = DbLedger::open(&tostr).unwrap(); db_ledger .write_entries(DEFAULT_SLOT_HEIGHT, 0, ledger_entries) .unwrap(); + genesis_block.write(&path).unwrap(); - tostr + path } #[cfg(test)] diff --git a/src/fullnode.rs b/src/fullnode.rs index d75d2bee9..48e7cf5a4 100644 --- a/src/fullnode.rs +++ b/src/fullnode.rs @@ -5,6 +5,7 @@ use crate::broadcast_service::BroadcastService; use crate::cluster_info::{ClusterInfo, Node, NodeInfo}; use crate::counter::Counter; use crate::db_ledger::DbLedger; +use crate::genesis_block::GenesisBlock; use crate::gossip_service::GossipService; use crate::leader_scheduler::LeaderScheduler; use crate::rpc::JsonRpcService; @@ -104,6 +105,7 @@ pub struct Fullnode { retransmit_socket: UdpSocket, tpu_sockets: Vec, broadcast_socket: UdpSocket, + genesis_block: GenesisBlock, db_ledger: Arc, vote_signer: Option>, } @@ -150,9 +152,9 @@ impl Fullnode { let leader_scheduler = Arc::new(RwLock::new(leader_scheduler)); info!("creating bank..."); - let db_ledger = Self::make_db_ledger(ledger_path); + let (genesis_block, db_ledger) = Self::make_db_ledger(ledger_path); let (bank, entry_height, last_entry_id) = - Self::new_bank_from_db_ledger(&db_ledger, leader_scheduler); + Self::new_bank_from_db_ledger(&genesis_block, &db_ledger, leader_scheduler); info!("creating networking stack..."); let local_gossip_addr = node.sockets.gossip.local_addr().unwrap(); @@ -169,16 +171,47 @@ impl Fullnode { info!("node entrypoint_addr: {:?}", entrypoint_addr); let entrypoint_info = entrypoint_addr.map(|i| NodeInfo::new_entry_point(&i)); - Self::new_with_bank( + Self::new_with_bank_and_db_ledger( keypair, vote_signer, bank, - Some(db_ledger), + genesis_block, + db_ledger, entry_height, &last_entry_id, node, entrypoint_info.as_ref(), - ledger_path, + sigverify_disabled, + rpc_port, + storage_rotate_count, + ) + } + + #[allow(clippy::too_many_arguments)] + pub fn new_with_bank( + keypair: Arc, + vote_signer: Option>, + bank: Bank, + ledger_path: &str, + entry_height: u64, + last_entry_id: &Hash, + node: Node, + entrypoint_info_option: Option<&NodeInfo>, + sigverify_disabled: bool, + rpc_port: Option, + storage_rotate_count: u64, + ) -> Self { + let (genesis_block, db_ledger) = Self::make_db_ledger(ledger_path); + Self::new_with_bank_and_db_ledger( + keypair, + vote_signer, + bank, + genesis_block, + db_ledger, + entry_height, + &last_entry_id, + node, + entrypoint_info_option, sigverify_disabled, rpc_port, storage_rotate_count, @@ -187,16 +220,16 @@ impl Fullnode { /// Create a fullnode instance acting as a leader or validator. #[allow(clippy::too_many_arguments)] - pub fn new_with_bank( + pub fn new_with_bank_and_db_ledger( keypair: Arc, vote_signer: Option>, bank: Bank, - db_ledger: Option>, + genesis_block: GenesisBlock, + db_ledger: Arc, entry_height: u64, last_entry_id: &Hash, mut node: Node, entrypoint_info_option: Option<&NodeInfo>, - ledger_path: &str, sigverify_disabled: bool, rpc_port: Option, storage_rotate_count: u64, @@ -216,8 +249,6 @@ impl Fullnode { let exit = Arc::new(AtomicBool::new(false)); let bank = Arc::new(bank); - let db_ledger = db_ledger.unwrap_or_else(|| Self::make_db_ledger(ledger_path)); - node.info.wallclock = timestamp(); let cluster_info = Arc::new(RwLock::new(ClusterInfo::new_with_keypair( node.info, @@ -373,6 +404,7 @@ impl Fullnode { retransmit_socket: node.sockets.retransmit, tpu_sockets: node.sockets.tpu, broadcast_socket: node.sockets.broadcast, + genesis_block, db_ledger, vote_signer, } @@ -392,6 +424,7 @@ impl Fullnode { // TODO: We can avoid building the bank again once RecordStage is // integrated with BankingStage let (new_bank, entry_height, last_id) = Self::new_bank_from_db_ledger( + &self.genesis_block, &self.db_ledger, Arc::new(RwLock::new(new_leader_scheduler)), ); @@ -566,10 +599,12 @@ impl Fullnode { } fn new_bank_from_db_ledger( + genesis_block: &GenesisBlock, db_ledger: &DbLedger, leader_scheduler: Arc>, ) -> (Bank, u64, Hash) { - let mut bank = Bank::new_with_builtin_programs(); + let mut bank = Bank::new(genesis_block); + leader_scheduler.write().unwrap().bootstrap_leader = genesis_block.bootstrap_leader_id; bank.leader_scheduler = leader_scheduler; let now = Instant::now(); @@ -580,7 +615,7 @@ impl Fullnode { // entry_height is the network-wide agreed height of the ledger. // initialize it from the input ledger info!( - "processed {} ledger in {}ms...", + "processed {} ledger entries in {}ms...", entry_height, duration_as_ms(&now.elapsed()) ); @@ -591,18 +626,22 @@ impl Fullnode { ledger_path: &str, leader_scheduler: Arc>, ) -> (Bank, u64, Hash) { - let db_ledger = Self::make_db_ledger(ledger_path); - Self::new_bank_from_db_ledger(&db_ledger, leader_scheduler) + let (genesis_block, db_ledger) = Self::make_db_ledger(ledger_path); + Self::new_bank_from_db_ledger(&genesis_block, &db_ledger, leader_scheduler) } pub fn get_leader_scheduler(&self) -> &Arc> { &self.bank.leader_scheduler } - fn make_db_ledger(ledger_path: &str) -> Arc { - Arc::new( + fn make_db_ledger(ledger_path: &str) -> (GenesisBlock, Arc) { + let db_ledger = Arc::new( DbLedger::open(ledger_path).expect("Expected to successfully open database ledger"), - ) + ); + + let genesis_block = + GenesisBlock::load(ledger_path).expect("Expected to successfully open genesis block"); + (genesis_block, db_ledger) } } @@ -663,12 +702,11 @@ mod tests { fn validator_exit() { let keypair = Keypair::new(); let tn = Node::new_localhost_with_pubkey(keypair.pubkey()); - let (mint, validator_ledger_path) = + let (genesis_block, _mint_keypair, validator_ledger_path) = create_tmp_genesis("validator_exit", 10_000, keypair.pubkey(), 1000); - let mut bank = Bank::new(&mint); + let mut bank = Bank::new(&genesis_block); let entry = tn.info.clone(); - let genesis_entries = &mint.create_entries(); - let entry_height = genesis_entries.len() as u64; + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( entry.id, @@ -682,12 +720,11 @@ mod tests { keypair, Some(Arc::new(signer)), bank, - None, + &validator_ledger_path, entry_height, &last_id, tn, Some(&entry), - &validator_ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -703,14 +740,14 @@ mod tests { .map(|i| { let keypair = Keypair::new(); let tn = Node::new_localhost_with_pubkey(keypair.pubkey()); - let (mint, validator_ledger_path) = create_tmp_genesis( + let (genesis_block, _mint_keypair, validator_ledger_path) = create_tmp_genesis( &format!("validator_parallel_exit_{}", i), 10_000, keypair.pubkey(), 1000, ); ledger_paths.push(validator_ledger_path.clone()); - let mut bank = Bank::new(&mint); + let mut bank = Bank::new(&genesis_block); let entry = tn.info.clone(); let leader_scheduler = Arc::new(RwLock::new( @@ -718,7 +755,7 @@ mod tests { )); bank.leader_scheduler = leader_scheduler; - let entry_height = mint.create_entries().len() as u64; + let entry_height = 0; let last_id = bank.last_id(); let keypair = Arc::new(keypair); let signer = VoteSignerProxy::new(&keypair, Box::new(LocalVoteSigner::default())); @@ -726,12 +763,11 @@ mod tests { keypair, Some(Arc::new(signer)), bank, - None, + &validator_ledger_path, entry_height, &last_id, tn, Some(&entry), - &validator_ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -762,17 +798,17 @@ mod tests { // Make a mint and a genesis entries for leader ledger let num_ending_ticks = 1; - let (_, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_leader_to_leader_transition", - 10_000, - num_ending_ticks, - bootstrap_leader_keypair.pubkey(), - 500, - ); + let (_genesis_block, _mint_keypair, bootstrap_leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_leader_to_leader_transition", + 10_000, + num_ending_ticks, + bootstrap_leader_keypair.pubkey(), + 500, + ); let initial_tick_height = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64); // Create the common leader scheduling configuration @@ -843,14 +879,15 @@ mod tests { let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey()); // Make a common mint and a genesis entry for both leader + validator's ledgers - let num_ending_ticks = 1; - let (mint, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_wrong_role_transition", - 10_000, - num_ending_ticks, - bootstrap_leader_keypair.pubkey(), - 500, - ); + let num_ending_ticks = 3; + let (_genesis_block, mint_keypair, bootstrap_leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_wrong_role_transition", + 10_000, + num_ending_ticks, + bootstrap_leader_keypair.pubkey(), + 500, + ); let last_id = genesis_entries .last() @@ -862,7 +899,7 @@ mod tests { let validator_keypair = Arc::new(validator_keypair); let (active_set_entries, validator_vote_account_id) = make_active_set_entries( &validator_keypair, - &mint.keypair(), + &mint_keypair, &last_id, &last_id, num_ending_ticks, @@ -870,7 +907,6 @@ mod tests { let genesis_tick_height = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64) + num_ending_ticks as u64; @@ -972,13 +1008,14 @@ mod tests { // Create validator identity let num_ending_ticks = 1; - let (mint, validator_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_validator_to_leader_transition", - 10_000, - num_ending_ticks, - leader_id, - 500, - ); + let (_genesis_block, mint_keypair, validator_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_validator_to_leader_transition", + 10_000, + num_ending_ticks, + leader_id, + 500, + ); let validator_keypair = Keypair::new(); let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey()); @@ -998,10 +1035,9 @@ mod tests { // // 2) A vote from the validator let (active_set_entries, _validator_vote_account_id) = - make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&validator_keypair, &mint_keypair, &last_id, &last_id, 0); let initial_tick_height = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64); let initial_non_tick_height = genesis_entries.len() as u64 - initial_tick_height; let active_set_entries_len = active_set_entries.len() as u64; @@ -1096,6 +1132,7 @@ mod tests { // Check the validator ledger for the correct entry + tick heights, we should've // transitioned after tick_height = bootstrap_height. let (bank, entry_height, _) = Fullnode::new_bank_from_db_ledger( + &validator.genesis_block, &validator.db_ledger, Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config))), ); diff --git a/src/genesis_block.rs b/src/genesis_block.rs new file mode 100644 index 000000000..53cefb77f --- /dev/null +++ b/src/genesis_block.rs @@ -0,0 +1,92 @@ +//! The `genesis_block` module is a library for generating the chain's genesis block. + +use solana_sdk::hash::{hash, Hash}; +use solana_sdk::pubkey::Pubkey; +use solana_sdk::signature::{Keypair, KeypairUtil}; +use std::fs::File; +use std::io::Write; +use std::path::Path; + +#[derive(Serialize, Deserialize, Debug)] +pub struct GenesisBlock { + pub bootstrap_leader_id: Pubkey, + pub bootstrap_leader_tokens: u64, + pub mint_id: Pubkey, + pub tokens: u64, +} + +impl GenesisBlock { + #[allow(clippy::new_ret_no_self)] + pub fn new(tokens: u64) -> (Self, Keypair) { + let mint_keypair = Keypair::new(); + ( + Self { + bootstrap_leader_id: Pubkey::default(), + bootstrap_leader_tokens: 0, + mint_id: mint_keypair.pubkey(), + tokens, + }, + mint_keypair, + ) + } + + pub fn new_with_leader( + tokens: u64, + bootstrap_leader_id: Pubkey, + bootstrap_leader_tokens: u64, + ) -> (Self, Keypair) { + let mint_keypair = Keypair::new(); + ( + Self { + bootstrap_leader_id, + bootstrap_leader_tokens, + mint_id: mint_keypair.pubkey(), + tokens, + }, + mint_keypair, + ) + } + + pub fn last_id(&self) -> Hash { + let serialized = serde_json::to_string(self).unwrap(); + hash(&serialized.into_bytes()) + } + + pub fn load(ledger_path: &str) -> Result { + let file = File::open(&Path::new(ledger_path).join("genesis.json"))?; + let genesis_block = serde_json::from_reader(file)?; + Ok(genesis_block) + } + + 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"))?; + file.write_all(&serialized.into_bytes()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_genesis_block_new() { + let (genesis_block, mint) = GenesisBlock::new(10_000); + assert_eq!(genesis_block.tokens, 10_000); + assert_eq!(genesis_block.mint_id, mint.pubkey()); + assert_eq!(genesis_block.bootstrap_leader_id, Pubkey::default()); + assert_eq!(genesis_block.bootstrap_leader_tokens, 0); + } + + #[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.tokens, 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_tokens, 123); + } +} diff --git a/src/leader_scheduler.rs b/src/leader_scheduler.rs index 0ca6fcd5d..1295aaef7 100644 --- a/src/leader_scheduler.rs +++ b/src/leader_scheduler.rs @@ -529,11 +529,11 @@ pub fn make_active_set_entries( #[cfg(test)] mod tests { use crate::bank::Bank; + use crate::genesis_block::GenesisBlock; use crate::leader_scheduler::{ LeaderScheduler, LeaderSchedulerConfig, DEFAULT_BOOTSTRAP_HEIGHT, DEFAULT_LEADER_ROTATION_INTERVAL, DEFAULT_SEED_ROTATION_INTERVAL, }; - use crate::mint::Mint; use crate::vote_signer_proxy::VoteSignerProxy; use hashbrown::HashSet; use solana_sdk::hash::Hash; @@ -580,17 +580,13 @@ mod tests { // Create the bank and validators, which are inserted in order of account balance let num_vote_account_tokens = 1; - let mint = Mint::new( + let (genesis_block, mint_keypair) = GenesisBlock::new( (((num_validators + 1) / 2) * (num_validators + 1) + num_vote_account_tokens * num_validators) as u64, ); - let bank = Bank::new(&mint); + let bank = Bank::new(&genesis_block); let mut validators = vec![]; - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let last_id = genesis_block.last_id(); for i in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); @@ -602,7 +598,7 @@ mod tests { // Give the validator some tokens bank.transfer( (i + 1 + num_vote_account_tokens) as u64, - &mint.keypair(), + &mint_keypair, new_pubkey, last_id, ) @@ -610,11 +606,15 @@ mod tests { // Create a vote account vote_signer - .new_vote_account(&bank, num_vote_account_tokens as u64, mint.last_id()) + .new_vote_account( + &bank, + num_vote_account_tokens as u64, + genesis_block.last_id(), + ) .unwrap(); // Vote to make the validator part of the active set for the entire test // (we made the active_window_length large enough at the beginning of the test) - push_vote(&vote_signer, &bank, 1, mint.last_id()); + push_vote(&vote_signer, &bank, 1, genesis_block.last_id()); } // The scheduled leader during the bootstrapping period (assuming a seed + schedule @@ -697,8 +697,8 @@ mod tests { fn test_active_set() { let leader_id = Keypair::new().pubkey(); let active_window_length = 1000; - let mint = Mint::new_with_leader(10000, leader_id, 500); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new_with_leader(10000, leader_id, 500); + let bank = Bank::new(&genesis_block); let leader_scheduler_config = LeaderSchedulerConfig::new(Some(100), Some(100), Some(100), Some(active_window_length)); @@ -716,18 +716,18 @@ mod tests { old_ids.insert(pk.clone()); // Give the account some stake - bank.transfer(5, &mint.keypair(), pk, mint.last_id()) + bank.transfer(5, &mint_keypair, pk, genesis_block.last_id()) .unwrap(); // Create a vote account let vote_signer = VoteSignerProxy::new(&Arc::new(new_keypair), Box::new(LocalVoteSigner::default())); vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); // Push a vote for the account - push_vote(&vote_signer, &bank, start_height, mint.last_id()); + push_vote(&vote_signer, &bank, start_height, genesis_block.last_id()); } // Insert a bunch of votes at height "start_height + active_window_length" @@ -738,21 +738,21 @@ mod tests { let pk = new_keypair.pubkey(); new_ids.insert(pk); // Give the account some stake - bank.transfer(5, &mint.keypair(), pk, mint.last_id()) + bank.transfer(5, &mint_keypair, pk, genesis_block.last_id()) .unwrap(); // Create a vote account let vote_signer = VoteSignerProxy::new(&Arc::new(new_keypair), Box::new(LocalVoteSigner::default())); vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); push_vote( &vote_signer, &bank, start_height + active_window_length, - mint.last_id(), + genesis_block.last_id(), ); } @@ -788,22 +788,19 @@ mod tests { #[test] fn test_rank_active_set() { let num_validators: usize = 101; - // Give mint sum(1..num_validators) tokens - let mint = Mint::new((((num_validators + 1) / 2) * (num_validators + 1)) as u64); - let bank = Bank::new(&mint); + // Give genesis_block sum(1..num_validators) tokens + let (genesis_block, mint_keypair) = + GenesisBlock::new((((num_validators + 1) / 2) * (num_validators + 1)) as u64); + let bank = Bank::new(&genesis_block); let mut validators = vec![]; - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let last_id = genesis_block.last_id(); for i in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); validators.push(new_validator); bank.transfer( (num_validators - i) as u64, - &mint.keypair(), + &mint_keypair, new_pubkey, last_id, ) @@ -851,20 +848,16 @@ mod tests { } // Break ties between validators with the same balances using public key - let mint = Mint::new(num_validators as u64); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(num_validators as u64); + let bank = Bank::new(&genesis_block); let mut tied_validators_pk = vec![]; - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let last_id = genesis_block.last_id(); for _ in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); tied_validators_pk.push(new_pubkey); - bank.transfer(1, &mint.keypair(), new_pubkey, last_id) + bank.transfer(1, &mint_keypair, new_pubkey, last_id) .unwrap(); } @@ -1002,17 +995,13 @@ mod tests { leader_scheduler.bootstrap_leader = bootstrap_leader_id; // Create the bank and validators - let mint = Mint::new( + let (genesis_block, mint_keypair) = GenesisBlock::new( ((((num_validators + 1) / 2) * (num_validators + 1)) + (num_vote_account_tokens * num_validators)) as u64, ); - let bank = Bank::new(&mint); + let bank = Bank::new(&genesis_block); let mut validators = vec![]; - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let last_id = genesis_block.last_id(); for i in 0..num_validators { let new_validator = Keypair::new(); let new_pubkey = new_validator.pubkey(); @@ -1024,7 +1013,7 @@ mod tests { // Give the validator some tokens bank.transfer( (i + 1 + num_vote_account_tokens) as u64, - &mint.keypair(), + &mint_keypair, new_pubkey, last_id, ) @@ -1032,7 +1021,11 @@ mod tests { // Create a vote account vote_signer - .new_vote_account(&bank, num_vote_account_tokens as u64, mint.last_id()) + .new_vote_account( + &bank, + num_vote_account_tokens as u64, + genesis_block.last_id(), + ) .unwrap(); // Vote at height i * active_window_length for validator i @@ -1040,7 +1033,7 @@ mod tests { &vote_signer, &bank, i * active_window_length + bootstrap_height, - mint.last_id(), + genesis_block.last_id(), ); } @@ -1065,8 +1058,8 @@ mod tests { let leader_keypair = Keypair::new(); let leader_id = leader_keypair.pubkey(); let active_window_length = 1000; - let mint = Mint::new_with_leader(10000, leader_id, 500); - let bank = Bank::new(&mint); + let (genesis_block, _mint_keypair) = GenesisBlock::new_with_leader(10000, leader_id, 500); + let bank = Bank::new(&genesis_block); let leader_scheduler_config = LeaderSchedulerConfig::new(Some(100), Some(100), Some(100), Some(active_window_length)); @@ -1084,12 +1077,22 @@ mod tests { ); // Create a vote account vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); // Vote twice - push_vote(&vote_signer, &bank, initial_vote_height, mint.last_id()); - push_vote(&vote_signer, &bank, initial_vote_height + 1, mint.last_id()); + push_vote( + &vote_signer, + &bank, + initial_vote_height, + genesis_block.last_id(), + ); + push_vote( + &vote_signer, + &bank, + initial_vote_height + 1, + genesis_block.last_id(), + ); let result = leader_scheduler.get_active_set(initial_vote_height + active_window_length, &bank); @@ -1205,20 +1208,17 @@ mod tests { leader_scheduler.bootstrap_leader = bootstrap_leader_id; // Create mint and bank - let mint = Mint::new_with_leader(10000, bootstrap_leader_id, 0); - let bank = Bank::new(&mint); - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let (genesis_block, mint_keypair) = + GenesisBlock::new_with_leader(10000, bootstrap_leader_id, 0); + let bank = Bank::new(&genesis_block); + let last_id = genesis_block.last_id(); let initial_vote_height = 1; // Create and add validator to the active set let validator_keypair = Keypair::new(); let validator_id = validator_keypair.pubkey(); if add_validator { - bank.transfer(5, &mint.keypair(), validator_id, last_id) + bank.transfer(5, &mint_keypair, validator_id, last_id) .unwrap(); // Create a vote account let vote_signer = VoteSignerProxy::new( @@ -1226,10 +1226,15 @@ mod tests { Box::new(LocalVoteSigner::default()), ); vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); - push_vote(&vote_signer, &bank, initial_vote_height, mint.last_id()); + push_vote( + &vote_signer, + &bank, + initial_vote_height, + genesis_block.last_id(), + ); } // Make sure the bootstrap leader, not the validator, is picked again on next slot @@ -1249,7 +1254,7 @@ mod tests { let vote_account_tokens = 1; bank.transfer( leader_stake + vote_account_tokens, - &mint.keypair(), + &mint_keypair, bootstrap_leader_id, last_id, ) @@ -1261,11 +1266,16 @@ mod tests { Box::new(LocalVoteSigner::default()), ); vote_signer - .new_vote_account(&bank, vote_account_tokens as u64, mint.last_id()) + .new_vote_account(&bank, vote_account_tokens as u64, genesis_block.last_id()) .unwrap(); // Add leader to the active set - push_vote(&vote_signer, &bank, initial_vote_height, mint.last_id()); + push_vote( + &vote_signer, + &bank, + initial_vote_height, + genesis_block.last_id(), + ); leader_scheduler.generate_schedule(bootstrap_height, &bank); @@ -1311,13 +1321,10 @@ mod tests { leader_scheduler.bootstrap_leader = bootstrap_leader_id; // Create mint and bank - let mint = Mint::new_with_leader(10000, bootstrap_leader_id, 500); - let bank = Bank::new(&mint); - let last_id = mint - .create_entries() - .last() - .expect("Mint should not create empty genesis entries") - .id; + let (genesis_block, mint_keypair) = + GenesisBlock::new_with_leader(10000, bootstrap_leader_id, 0); + let bank = Bank::new(&genesis_block); + let last_id = genesis_block.last_id(); let initial_vote_height = 1; // No schedule generated yet, so for all heights <= bootstrap height, the @@ -1378,30 +1385,40 @@ mod tests { let validator_id = validator_keypair.pubkey(); // Create a vote account for the validator - bank.transfer(5, &mint.keypair(), validator_id, last_id) + bank.transfer(5, &mint_keypair, validator_id, last_id) .unwrap(); let vote_signer = VoteSignerProxy::new( &Arc::new(validator_keypair), Box::new(LocalVoteSigner::default()), ); vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); - push_vote(&vote_signer, &bank, initial_vote_height, mint.last_id()); + push_vote( + &vote_signer, + &bank, + initial_vote_height, + genesis_block.last_id(), + ); // Create a vote account for the leader - bank.transfer(5, &mint.keypair(), bootstrap_leader_id, last_id) + bank.transfer(5, &mint_keypair, bootstrap_leader_id, last_id) .unwrap(); let vote_signer = VoteSignerProxy::new( &Arc::new(bootstrap_leader_keypair), Box::new(LocalVoteSigner::default()), ); vote_signer - .new_vote_account(&bank, 1 as u64, mint.last_id()) + .new_vote_account(&bank, 1 as u64, genesis_block.last_id()) .unwrap(); // Add leader to the active set - push_vote(&vote_signer, &bank, initial_vote_height, mint.last_id()); + push_vote( + &vote_signer, + &bank, + initial_vote_height, + genesis_block.last_id(), + ); // Generate the schedule leader_scheduler.generate_schedule(bootstrap_height, &bank); diff --git a/src/lib.rs b/src/lib.rs index 24c88634b..632c9cdb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,10 +38,10 @@ pub mod entry; pub mod erasure; pub mod fetch_stage; pub mod fullnode; +pub mod genesis_block; pub mod gossip_service; pub mod leader_scheduler; pub mod local_vote_signer_service; -pub mod mint; pub mod packet; pub mod poh; pub mod poh_recorder; diff --git a/src/mint.rs b/src/mint.rs deleted file mode 100644 index 69a84c25b..000000000 --- a/src/mint.rs +++ /dev/null @@ -1,160 +0,0 @@ -//! The `mint` module is a library for generating the chain's genesis block. - -use crate::entry::Entry; -use solana_sdk::hash::{hash, Hash}; -use solana_sdk::pubkey::Pubkey; -use solana_sdk::signature::{gen_pkcs8, Keypair, KeypairUtil}; -use solana_sdk::system_transaction::SystemTransaction; -use solana_sdk::transaction::Transaction; -use untrusted::Input; - -#[derive(Serialize, Deserialize, Debug)] -pub struct Mint { - pub pkcs8: Vec, - pubkey: Pubkey, - pub tokens: u64, - pub bootstrap_leader_id: Pubkey, - pub bootstrap_leader_tokens: u64, -} - -pub const NUM_GENESIS_ENTRIES: usize = 3; - -impl Mint { - pub fn new_with_pkcs8( - tokens: u64, - pkcs8: Vec, - bootstrap_leader_id: Pubkey, - bootstrap_leader_tokens: u64, - ) -> Self { - let keypair = - Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new"); - let pubkey = keypair.pubkey(); - Mint { - pkcs8, - pubkey, - tokens, - bootstrap_leader_id, - bootstrap_leader_tokens, - } - } - - pub fn new_with_leader( - tokens: u64, - bootstrap_leader: Pubkey, - bootstrap_leader_tokens: u64, - ) -> Self { - let pkcs8 = gen_pkcs8().expect("generate_pkcs8 in mint pub fn new"); - Self::new_with_pkcs8(tokens, pkcs8, bootstrap_leader, bootstrap_leader_tokens) - } - - pub fn new(tokens: u64) -> Self { - let pkcs8 = gen_pkcs8().expect("generate_pkcs8 in mint pub fn new"); - Self::new_with_pkcs8(tokens, pkcs8, Pubkey::default(), 0) - } - - pub fn seed(&self) -> Hash { - hash(&self.pkcs8) - } - - pub fn last_id(&self) -> Hash { - self.create_entries().last().unwrap().id - } - - pub fn keypair(&self) -> Keypair { - Keypair::from_pkcs8(Input::from(&self.pkcs8)).expect("from_pkcs8 in mint pub fn keypair") - } - - pub fn pubkey(&self) -> Pubkey { - self.pubkey - } - - pub fn create_transaction(&self) -> Vec { - let keypair = self.keypair(); - // Check if creating the leader genesis entries is necessary - if self.bootstrap_leader_id == Pubkey::default() { - let tx = Transaction::system_move(&keypair, self.pubkey(), self.tokens, self.seed(), 0); - vec![tx] - } else { - // Create moves from mint to itself (deposit), and then a move from the mint - // to the bootstrap leader - let moves = vec![ - (self.pubkey(), self.tokens), - (self.bootstrap_leader_id, self.bootstrap_leader_tokens), - ]; - vec![Transaction::system_move_many( - &keypair, - &moves, - self.seed(), - 0, - )] - } - } - - pub fn create_entries(&self) -> Vec { - let e0 = Entry::new(&self.seed(), 0, 0, vec![]); - let e1 = Entry::new(&e0.id, 0, 1, self.create_transaction()); - let e2 = Entry::new(&e1.id, 0, 1, vec![]); // include a tick - let genesis = vec![e0, e1, e2]; - assert_eq!(NUM_GENESIS_ENTRIES, genesis.len()); - genesis - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::entry::EntrySlice; - use bincode::deserialize; - use solana_sdk::system_instruction::SystemInstruction; - use solana_sdk::system_program; - - #[test] - fn test_create_transactions() { - let mut transactions = Mint::new(100).create_transaction().into_iter(); - let tx = transactions.next().unwrap(); - assert_eq!(tx.instructions.len(), 1); - assert!(system_program::check_id(tx.program_id(0))); - let instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap(); - if let SystemInstruction::Move { tokens } = instruction { - assert_eq!(tokens, 100); - } - assert_eq!(transactions.next(), None); - } - - #[test] - fn test_create_leader_transactions() { - let dummy_leader_id = Keypair::new().pubkey(); - let dummy_leader_tokens = 1; - let mut transactions = Mint::new_with_leader(100, dummy_leader_id, dummy_leader_tokens) - .create_transaction() - .into_iter(); - let tx = transactions.next().unwrap(); - assert_eq!(tx.instructions.len(), 2); - assert!(system_program::check_id(tx.program_id(0))); - assert!(system_program::check_id(tx.program_id(1))); - let instruction: SystemInstruction = deserialize(tx.userdata(0)).unwrap(); - if let SystemInstruction::Move { tokens } = instruction { - assert_eq!(tokens, 100); - } - let instruction: SystemInstruction = deserialize(tx.userdata(1)).unwrap(); - if let SystemInstruction::Move { tokens } = instruction { - assert_eq!(tokens, 1); - } - assert_eq!(transactions.next(), None); - } - - #[test] - fn test_verify_entries() { - let entries = Mint::new(100).create_entries(); - assert!(entries[..].verify(&entries[0].id)); - } - - #[test] - fn test_verify_leader_entries() { - let dummy_leader_id = Keypair::new().pubkey(); - let dummy_leader_tokens = 1; - let entries = - Mint::new_with_leader(100, dummy_leader_id, dummy_leader_tokens).create_entries(); - assert!(entries[..].verify(&entries[0].id)); - } -} diff --git a/src/poh_recorder.rs b/src/poh_recorder.rs index 11e3282be..b34c79967 100644 --- a/src/poh_recorder.rs +++ b/src/poh_recorder.rs @@ -115,7 +115,7 @@ impl PohRecorder { #[cfg(test)] mod tests { use super::*; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use crate::test_tx::test_tx; use solana_sdk::hash::hash; use std::sync::mpsc::channel; @@ -123,8 +123,8 @@ mod tests { #[test] fn test_poh() { - let mint = Mint::new(1); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, _mint_keypair) = GenesisBlock::new(1); + let bank = Arc::new(Bank::new(&genesis_block)); let prev_id = bank.last_id(); let (entry_sender, entry_receiver) = channel(); let mut poh_recorder = PohRecorder::new(bank, entry_sender, prev_id, Some(3)); diff --git a/src/poh_service.rs b/src/poh_service.rs index 2f758ffd4..1d3d1de46 100644 --- a/src/poh_service.rs +++ b/src/poh_service.rs @@ -98,7 +98,7 @@ impl Service for PohService { mod tests { use super::{Config, PohService}; use crate::bank::Bank; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use crate::poh_recorder::PohRecorder; use crate::result::Result; use crate::service::Service; @@ -111,8 +111,8 @@ mod tests { #[test] fn test_poh_service() { - let mint = Mint::new(1); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, _mint_keypair) = GenesisBlock::new(1); + let bank = Arc::new(Bank::new(&genesis_block)); let prev_id = bank.last_id(); let (entry_sender, entry_receiver) = channel(); let poh_recorder = PohRecorder::new(bank, entry_sender, prev_id, None); diff --git a/src/replay_stage.rs b/src/replay_stage.rs index ef62756dc..109bbe9aa 100644 --- a/src/replay_stage.rs +++ b/src/replay_stage.rs @@ -318,8 +318,8 @@ mod test { let old_leader_id = Keypair::new().pubkey(); // Create a ledger - let num_ending_ticks = 1; - let (mint, my_ledger_path, genesis_entries) = create_tmp_sample_ledger( + let num_ending_ticks = 3; + let (_, mint_keypair, my_ledger_path, genesis_entries) = create_tmp_sample_ledger( "test_replay_stage_leader_rotation_exit", 10_000, num_ending_ticks, @@ -336,11 +336,10 @@ mod test { // 1) Give the validator a nonzero number of tokens 2) A vote from the validator . // This will cause leader rotation after the bootstrap height let (active_set_entries, vote_account_id) = - make_active_set_entries(&my_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&my_keypair, &mint_keypair, &last_id, &last_id, 0); last_id = active_set_entries.last().unwrap().id; let initial_tick_height = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64); let active_set_entries_len = active_set_entries.len() as u64; let initial_non_tick_height = genesis_entries.len() as u64 - initial_tick_height; @@ -357,7 +356,7 @@ mod test { .unwrap(); } - // Set up the LeaderScheduler so that this this node becomes the leader at + // Set up the LeaderScheduler so that this node becomes the leader at // bootstrap_height = num_bootstrap_slots * leader_rotation_interval let leader_rotation_interval = 16; let num_bootstrap_slots = 2; @@ -395,7 +394,6 @@ mod test { let total_entries_to_send = (bootstrap_height + extra_entries) as usize; let num_hashes = 1; let mut entries_to_send = vec![]; - while entries_to_send.len() < total_entries_to_send { let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]); last_id = entry.id; @@ -406,10 +404,10 @@ mod test { // Add on the only entries that weren't ticks to the bootstrap height to get the // total expected entry length - let leader_rotation_index = (bootstrap_height - initial_tick_height - 1) as usize; + let leader_rotation_index = (bootstrap_height - initial_tick_height) as usize; let expected_entry_height = - bootstrap_height + initial_non_tick_height + active_set_entries_len; - let expected_last_id = entries_to_send[leader_rotation_index].id; + bootstrap_height + initial_non_tick_height + active_set_entries_len - 1; + let expected_last_id = entries_to_send[leader_rotation_index - 2].id; entry_sender.send(entries_to_send.clone()).unwrap(); // Wait for replay_stage to exit and check return value is correct @@ -425,11 +423,11 @@ mod test { // Check that the entries on the ledger writer channel are correct let received_ticks = ledger_writer_recv .recv() - .expect("Expected to recieve an entry on the ledger writer receiver"); + .expect("Expected to receive an entry on the ledger writer receiver"); assert_eq!( &received_ticks[..], - &entries_to_send[..leader_rotation_index + 1] + &entries_to_send[..leader_rotation_index - 1] ); assert_eq!(exit.load(Ordering::Relaxed), true); @@ -448,14 +446,15 @@ mod test { let leader_id = Keypair::new().pubkey(); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default())); - let num_ending_ticks = 0; - let (_, my_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_vote_error_replay_stage_correctness", - 10_000, - num_ending_ticks, - leader_id, - 500, - ); + let num_ending_ticks = 1; + let (_genesis_block, _mint_keypair, my_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_vote_error_replay_stage_correctness", + 10_000, + num_ending_ticks, + leader_id, + 500, + ); let initial_entry_len = genesis_entries.len(); @@ -525,13 +524,14 @@ mod test { let leader_id = Keypair::new().pubkey(); // Create the ledger - let (mint, my_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_vote_error_replay_stage_leader_rotation", - 10_000, - 0, - leader_id, - 500, - ); + let (_genesis_block, mint_keypair, my_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_vote_error_replay_stage_leader_rotation", + 10_000, + 1, + leader_id, + 500, + ); let mut last_id = genesis_entries .last() @@ -543,11 +543,10 @@ mod test { // 1) Give the validator a nonzero number of tokens 2) A vote from the validator. // This will cause leader rotation after the bootstrap height let (active_set_entries, vote_account_id) = - make_active_set_entries(&my_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&my_keypair, &mint_keypair, &last_id, &last_id, 0); last_id = active_set_entries.last().unwrap().id; let initial_tick_height = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64); let active_set_entries_len = active_set_entries.len() as u64; let initial_non_tick_height = genesis_entries.len() as u64 - initial_tick_height; @@ -614,10 +613,10 @@ mod test { // Add on the only entries that weren't ticks to the bootstrap height to get the // total expected entry length let expected_entry_height = - bootstrap_height + initial_non_tick_height + active_set_entries_len; - let leader_rotation_index = (bootstrap_height - initial_tick_height - 1) as usize; + bootstrap_height + initial_non_tick_height + active_set_entries_len - 1; + let leader_rotation_index = (bootstrap_height - initial_tick_height - 2) as usize; let mut expected_last_id = Hash::default(); - for i in 0..total_entries_to_send { + for i in 0..total_entries_to_send - 1 { let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]); last_id = entry.id; entry_sender @@ -632,10 +631,12 @@ mod test { if i == leader_rotation_index { expected_last_id = entry.id; } + debug!( + "loop: i={}, leader_rotation_index={}, entry={:?}", + i, leader_rotation_index, entry, + ); } - assert_ne!(expected_last_id, Hash::default()); - // Wait for replay_stage to exit and check return value is correct assert_eq!( Some(ReplayStageReturnType::LeaderRotation( @@ -645,6 +646,8 @@ mod test { )), replay_stage.join().expect("replay stage join") ); + assert_ne!(expected_last_id, Hash::default()); + assert_eq!(exit.load(Ordering::Relaxed), true); let _ignored = remove_dir_all(&my_ledger_path); } diff --git a/src/rpc.rs b/src/rpc.rs index 775f324da..3d16be534 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -447,8 +447,8 @@ mod tests { use super::*; use crate::bank::Bank; use crate::cluster_info::NodeInfo; + use crate::genesis_block::GenesisBlock; use crate::jsonrpc_core::Response; - use crate::mint::Mint; use solana_sdk::hash::{hash, Hash}; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction::SystemTransaction; @@ -456,11 +456,11 @@ mod tests { use std::net::{IpAddr, Ipv4Addr, SocketAddr}; fn start_rpc_handler_with_tx(pubkey: Pubkey) -> (MetaIoHandler, Meta, Hash, Keypair) { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let last_id = bank.last_id(); - let tx = Transaction::system_move(&alice.keypair(), pubkey, 20, last_id, 0); + let tx = Transaction::system_move(&alice, pubkey, 20, last_id, 0); bank.process_transaction(&tx).expect("process transaction"); let request_processor = Arc::new(RwLock::new(JsonRpcRequestProcessor::new(Arc::new(bank)))); @@ -481,13 +481,13 @@ mod tests { drone_addr, rpc_addr, }; - (io, meta, last_id, alice.keypair()) + (io, meta, last_id, alice) } #[test] fn test_rpc_new() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let cluster_info = Arc::new(RwLock::new(ClusterInfo::new(NodeInfo::default()))); let rpc_addr = SocketAddr::new( IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), @@ -516,14 +516,14 @@ mod tests { #[test] fn test_rpc_request_processor_new() { - let alice = Mint::new(10_000); + let (genesis_block, alice) = GenesisBlock::new(10_000); let bob_pubkey = Keypair::new().pubkey(); - let bank = Bank::new(&alice); + let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); let request_processor = JsonRpcRequestProcessor::new(arc_bank.clone()); thread::spawn(move || { let last_id = arc_bank.last_id(); - let tx = Transaction::system_move(&alice.keypair(), bob_pubkey, 20, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); arc_bank .process_transaction(&tx) .expect("process transaction"); @@ -536,7 +536,7 @@ mod tests { #[test] fn test_rpc_get_balance() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, _last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, _last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"getBalance","params":["{}"]}}"#, @@ -554,7 +554,7 @@ mod tests { #[test] fn test_rpc_get_tx_count() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, _last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, _last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getTransactionCount"}}"#); let res = io.handle_request_sync(&req, meta); @@ -569,7 +569,7 @@ mod tests { #[test] fn test_rpc_get_account_info() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, _last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, _last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["{}"]}}"#, @@ -597,8 +597,8 @@ mod tests { #[test] fn test_rpc_confirm_tx() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, last_id, alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); - let tx = Transaction::system_move(&alice_keypair, bob_pubkey, 20, last_id, 0); + let (io, meta, last_id, alice) = start_rpc_handler_with_tx(bob_pubkey); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"confirmTransaction","params":["{}"]}}"#, @@ -616,8 +616,8 @@ mod tests { #[test] fn test_rpc_get_signature_status() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, last_id, alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); - let tx = Transaction::system_move(&alice_keypair, bob_pubkey, 20, last_id, 0); + let (io, meta, last_id, alice) = start_rpc_handler_with_tx(bob_pubkey); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":["{}"]}}"#, @@ -632,7 +632,7 @@ mod tests { assert_eq!(expected, result); // Test getSignatureStatus request on unprocessed tx - let tx = Transaction::system_move(&alice_keypair, bob_pubkey, 10, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 10, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"getSignatureStatus","params":["{}"]}}"#, tx.signatures[0] @@ -649,7 +649,7 @@ mod tests { #[test] fn test_rpc_get_confirmation() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, _last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, _last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getConfirmationTime"}}"#); let res = io.handle_request_sync(&req, meta); @@ -664,7 +664,7 @@ mod tests { #[test] fn test_rpc_get_last_id() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); let req = format!(r#"{{"jsonrpc":"2.0","id":1,"method":"getLastId"}}"#); let res = io.handle_request_sync(&req, meta); @@ -679,7 +679,7 @@ mod tests { #[test] fn test_rpc_fail_request_airdrop() { let bob_pubkey = Keypair::new().pubkey(); - let (io, meta, _last_id, _alice_keypair) = start_rpc_handler_with_tx(bob_pubkey); + let (io, meta, _last_id, _alice) = start_rpc_handler_with_tx(bob_pubkey); // Expect internal error because no leader is running let req = format!( @@ -698,8 +698,8 @@ mod tests { #[test] fn test_rpc_send_bad_tx() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, _) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let mut io = MetaIoHandler::default(); let rpc = RpcSolImpl; diff --git a/src/rpc_pubsub.rs b/src/rpc_pubsub.rs index e32a7c8b9..931584378 100644 --- a/src/rpc_pubsub.rs +++ b/src/rpc_pubsub.rs @@ -369,9 +369,9 @@ impl RpcSolPubSub for RpcSolPubSubImpl { #[cfg(test)] mod tests { use super::*; + use crate::genesis_block::GenesisBlock; use crate::jsonrpc_core::futures::sync::mpsc; use crate::jsonrpc_macros::pubsub::{Subscriber, SubscriptionId}; - use crate::mint::Mint; use solana_sdk::budget_program; use solana_sdk::budget_transaction::BudgetTransaction; use solana_sdk::signature::{Keypair, KeypairUtil}; @@ -382,8 +382,8 @@ mod tests { #[test] fn test_pubsub_new() { - let alice = Mint::new(10_000); - let bank = Bank::new(&alice); + let (genesis_block, _) = GenesisBlock::new(10_000); + let bank = Bank::new(&genesis_block); let pubsub_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0); let pubsub_service = PubSubService::new(&Arc::new(bank), pubsub_addr); let thread = pubsub_service.thread_hdl.thread(); @@ -393,10 +393,10 @@ mod tests { #[test] #[ignore] fn test_signature_subscribe() { - let alice = Mint::new(10_000); + let (genesis_block, alice) = GenesisBlock::new(10_000); let bob = Keypair::new(); let bob_pubkey = bob.pubkey(); - let bank = Bank::new(&alice); + let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); let last_id = arc_bank.last_id(); @@ -409,7 +409,7 @@ mod tests { io.extend_with(rpc.to_delegate()); // Test signature subscription - let tx = Transaction::system_move(&alice.keypair(), bob_pubkey, 20, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"signatureSubscribe","params":["{}"]}}"#, @@ -451,7 +451,7 @@ mod tests { } // Test subscription id increment - let tx = Transaction::system_move(&alice.keypair(), bob_pubkey, 10, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 10, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"signatureSubscribe","params":["{}"]}}"#, tx.signatures[0].to_string() @@ -468,9 +468,9 @@ mod tests { #[test] fn test_signature_unsubscribe() { - let alice = Mint::new(10_000); + let (genesis_block, alice) = GenesisBlock::new(10_000); let bob_pubkey = Keypair::new().pubkey(); - let bank = Bank::new(&alice); + let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); let last_id = arc_bank.last_id(); @@ -482,7 +482,7 @@ mod tests { let rpc = RpcSolPubSubImpl::new(rpc_bank.clone()); io.extend_with(rpc.to_delegate()); - let tx = Transaction::system_move(&alice.keypair(), bob_pubkey, 20, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"signatureSubscribe","params":["{}"]}}"#, tx.signatures[0].to_string() @@ -517,7 +517,7 @@ mod tests { #[test] #[ignore] fn test_account_subscribe() { - let alice = Mint::new(10_000); + let (genesis_block, alice) = GenesisBlock::new(10_000); let bob_pubkey = Keypair::new().pubkey(); let witness = Keypair::new(); let contract_funds = Keypair::new(); @@ -525,7 +525,7 @@ mod tests { let budget_program_id = budget_program::id(); let loader = Pubkey::default(); // TODO let executable = false; // TODO - let bank = Bank::new(&alice); + let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); let last_id = arc_bank.last_id(); @@ -565,7 +565,7 @@ mod tests { assert_eq!(expected, result); let tx = Transaction::system_create( - &alice.keypair(), + &alice, contract_funds.pubkey(), last_id, 50, @@ -578,7 +578,7 @@ mod tests { .expect("process transaction"); let tx = Transaction::system_create( - &alice.keypair(), + &alice, contract_state.pubkey(), last_id, 1, @@ -660,7 +660,7 @@ mod tests { assert_eq!(serde_json::to_string(&expected).unwrap(), response); } - let tx = Transaction::system_new(&alice.keypair(), witness.pubkey(), 1, last_id); + let tx = Transaction::system_new(&alice, witness.pubkey(), 1, last_id); arc_bank .process_transaction(&tx) .expect("process transaction"); @@ -703,9 +703,9 @@ mod tests { #[test] fn test_account_unsubscribe() { - let alice = Mint::new(10_000); + let (genesis_block, _) = GenesisBlock::new(10_000); let bob_pubkey = Keypair::new().pubkey(); - let bank = Bank::new(&alice); + let bank = Bank::new(&genesis_block); let arc_bank = Arc::new(bank); let (sender, _receiver) = mpsc::channel(1); @@ -750,12 +750,12 @@ mod tests { #[test] fn test_check_account_subscribe() { - let mint = Mint::new(100); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(100); + let bank = Bank::new(&genesis_block); let alice = Keypair::new(); let last_id = bank.last_id(); let tx = Transaction::system_create( - &mint.keypair(), + &mint_keypair, alice.pubkey(), last_id, 1, @@ -796,11 +796,11 @@ mod tests { } #[test] fn test_check_signature_subscribe() { - let mint = Mint::new(100); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(100); + let bank = Bank::new(&genesis_block); let alice = Keypair::new(); let last_id = bank.last_id(); - let tx = Transaction::system_move(&mint.keypair(), alice.pubkey(), 20, last_id, 0); + let tx = Transaction::system_move(&mint_keypair, alice.pubkey(), 20, last_id, 0); let signature = tx.signatures[0]; bank.process_transaction(&tx).unwrap(); diff --git a/src/storage_stage.rs b/src/storage_stage.rs index d286dc29a..7d0545e5b 100644 --- a/src/storage_stage.rs +++ b/src/storage_stage.rs @@ -500,7 +500,7 @@ mod tests { let keypair = Arc::new(Keypair::new()); let exit = Arc::new(AtomicBool::new(false)); - let (_mint, ledger_path, genesis_entries) = create_tmp_sample_ledger( + let (_genesis_block, _mint, ledger_path, genesis_entries) = create_tmp_sample_ledger( "storage_stage_process_entries", 1000, 1, @@ -568,7 +568,7 @@ mod tests { let keypair = Arc::new(Keypair::new()); let exit = Arc::new(AtomicBool::new(false)); - let (_mint, ledger_path, genesis_entries) = create_tmp_sample_ledger( + let (_genesis_block, _mint, ledger_path, genesis_entries) = create_tmp_sample_ledger( "storage_stage_process_entries", 1000, 1, diff --git a/src/thin_client.rs b/src/thin_client.rs index b2ea5758c..3f9f58023 100644 --- a/src/thin_client.rs +++ b/src/thin_client.rs @@ -441,10 +441,10 @@ mod tests { use super::*; use crate::bank::Bank; use crate::cluster_info::Node; - use crate::db_ledger::create_tmp_ledger_with_mint; + use crate::db_ledger::create_tmp_ledger; use crate::fullnode::Fullnode; + use crate::genesis_block::GenesisBlock; use crate::leader_scheduler::LeaderScheduler; - use crate::mint::Mint; use crate::storage_stage::STORAGE_ROTATE_TEST_COUNT; use crate::vote_signer_proxy::VoteSignerProxy; use bincode::{deserialize, serialize}; @@ -462,11 +462,11 @@ mod tests { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let ledger_path = create_tmp_ledger("thin_client", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -480,12 +480,11 @@ mod tests { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -500,9 +499,7 @@ mod tests { let confirmation = client.get_confirmation_time(); assert_eq!(confirmation, 18446744073709551615); let last_id = client.get_last_id(); - let signature = client - .transfer(500, &alice.keypair(), bob_pubkey, &last_id) - .unwrap(); + let signature = client.transfer(500, &alice, bob_pubkey, &last_id).unwrap(); client.poll_for_signature(&signature).unwrap(); let balance = client.get_balance(&bob_pubkey); assert_eq!(balance.unwrap(), 500); @@ -519,11 +516,11 @@ mod tests { solana_logger::setup(); let leader_keypair = Arc::new(Keypair::new()); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); let leader_data = leader.info.clone(); - let ledger_path = create_tmp_ledger_with_mint("bad_sig", &alice); + let ledger_path = create_tmp_ledger("bad_sig", &genesis_block); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -537,12 +534,11 @@ mod tests { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, 0, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -554,13 +550,13 @@ mod tests { let mut client = ThinClient::new(leader_data.rpc, leader_data.tpu, transactions_socket); let last_id = client.get_last_id(); - let tx = Transaction::system_new(&alice.keypair(), bob_pubkey, 500, last_id); + let tx = Transaction::system_new(&alice, bob_pubkey, 500, last_id); let _sig = client.transfer_signed(&tx).unwrap(); let last_id = client.get_last_id(); - let mut tr2 = Transaction::system_new(&alice.keypair(), bob_pubkey, 501, last_id); + let mut tr2 = Transaction::system_new(&alice, bob_pubkey, 501, last_id); let mut instruction2 = deserialize(tr2.userdata(0)).unwrap(); if let SystemInstruction::Move { ref mut tokens } = instruction2 { *tokens = 502; @@ -580,11 +576,11 @@ mod tests { solana_logger::setup(); let leader_keypair = Arc::new(Keypair::new()); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); let leader_data = leader.info.clone(); - let ledger_path = create_tmp_ledger_with_mint("client_check_signature", &alice); + let ledger_path = create_tmp_ledger("client_check_signature", &genesis_block); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -593,18 +589,17 @@ mod tests { let vote_account_keypair = Arc::new(Keypair::new()); let vote_signer = VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); - let entry_height = alice.create_entries().len() as u64; + let entry_height = 0; let last_id = bank.last_id(); let server = Fullnode::new_with_bank( leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -614,9 +609,7 @@ mod tests { let transactions_socket = UdpSocket::bind("0.0.0.0:0").unwrap(); let mut client = ThinClient::new(leader_data.rpc, leader_data.tpu, transactions_socket); let last_id = client.get_last_id(); - let signature = client - .transfer(500, &alice.keypair(), bob_pubkey, &last_id) - .unwrap(); + let signature = client.transfer(500, &alice, bob_pubkey, &last_id).unwrap(); assert!(client.poll_for_signature(&signature).is_ok()); @@ -629,14 +622,12 @@ mod tests { solana_logger::setup(); let leader_keypair = Arc::new(Keypair::new()); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); - let mint = Mint::new(10_000); - let mut bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let leader_data = leader.info.clone(); - let ledger_path = create_tmp_ledger_with_mint("client_check_signature", &mint); - - let genesis_entries = &mint.create_entries(); - let entry_height = genesis_entries.len() as u64; + let ledger_path = create_tmp_ledger("client_check_signature", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, ))); @@ -650,12 +641,11 @@ mod tests { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, - &genesis_entries.last().unwrap().id, + &genesis_block.last_id(), leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -669,7 +659,7 @@ mod tests { let validator_keypair = Keypair::new(); let last_id = client.get_last_id(); let signature = client - .transfer(500, &mint.keypair(), validator_keypair.pubkey(), &last_id) + .transfer(500, &mint_keypair, validator_keypair.pubkey(), &last_id) .unwrap(); assert!(client.poll_for_signature(&signature).is_ok()); @@ -728,11 +718,11 @@ mod tests { solana_logger::setup(); let leader_keypair = Arc::new(Keypair::new()); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_keypair = Keypair::new(); let leader_data = leader.info.clone(); - let ledger_path = create_tmp_ledger_with_mint("zero_balance_check", &alice); + let ledger_path = create_tmp_ledger("zero_balance_check", &genesis_block); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -742,17 +732,16 @@ mod tests { let vote_signer = VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); let last_id = bank.last_id(); - let entry_height = alice.create_entries().len() as u64; + let entry_height = 0; let server = Fullnode::new_with_bank( leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, @@ -765,7 +754,7 @@ mod tests { // give bob 500 tokens let signature = client - .transfer(500, &alice.keypair(), bob_keypair.pubkey(), &last_id) + .transfer(500, &alice, bob_keypair.pubkey(), &last_id) .unwrap(); assert!(client.poll_for_signature(&signature).is_ok()); @@ -775,7 +764,7 @@ mod tests { // take them away let signature = client - .transfer(500, &bob_keypair, alice.keypair().pubkey(), &last_id) + .transfer(500, &bob_keypair, alice.pubkey(), &last_id) .unwrap(); assert!(client.poll_for_signature(&signature).is_ok()); diff --git a/src/tvu.rs b/src/tvu.rs index 75b52963a..1dcc1e6ba 100644 --- a/src/tvu.rs +++ b/src/tvu.rs @@ -179,7 +179,7 @@ pub mod tests { use crate::gossip_service::GossipService; use crate::leader_scheduler::LeaderScheduler; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use crate::packet::SharedBlob; use crate::service::Service; use crate::storage_stage::STORAGE_ROTATE_TEST_COUNT; @@ -251,12 +251,12 @@ pub mod tests { ); let starting_balance = 10_000; - let mint = Mint::new(starting_balance); + let (genesis_block, mint_keypair) = GenesisBlock::new(starting_balance); let tvu_addr = target1.info.tvu; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_id, ))); - let mut bank = Bank::new(&mint); + let mut bank = Bank::new(&genesis_block); bank.leader_scheduler = leader_scheduler; let bank = Arc::new(bank); @@ -305,7 +305,7 @@ pub mod tests { cur_hash = entry_tick0.id; let tx0 = Transaction::system_new( - &mint.keypair(), + &mint_keypair, bob_keypair.pubkey(), transfer_amount, cur_hash, @@ -348,7 +348,7 @@ pub mod tests { trace!("got msg"); } - let alice_balance = bank.get_balance(&mint.keypair().pubkey()); + let alice_balance = bank.get_balance(&mint_keypair.pubkey()); assert_eq!(alice_balance, alice_ref_balance); let bob_balance = bank.get_balance(&bob_keypair.pubkey()); diff --git a/src/vote_signer_proxy.rs b/src/vote_signer_proxy.rs index ad6b5a926..24aee6bfc 100644 --- a/src/vote_signer_proxy.rs +++ b/src/vote_signer_proxy.rs @@ -206,7 +206,7 @@ impl VoteSignerProxy { mod test { use crate::bank::Bank; use crate::cluster_info::{ClusterInfo, Node}; - use crate::mint::Mint; + use crate::genesis_block::GenesisBlock; use crate::vote_signer_proxy::VoteSignerProxy; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_vote_signer::rpc::LocalVoteSigner; @@ -229,8 +229,8 @@ mod test { let my_node = Node::new_localhost_with_pubkey(my_id); let cluster_info = Arc::new(RwLock::new(ClusterInfo::new(my_node.info.clone()))); - let mint = Mint::new_with_leader(10000, my_id, 500); - let bank = Arc::new(Bank::new(&mint)); + let (genesis_block, _) = GenesisBlock::new_with_leader(10000, my_id, 500); + let bank = Arc::new(Bank::new(&genesis_block)); let (sender, receiver) = channel(); assert_eq!(signer.unsent_votes.read().unwrap().len(), 0); diff --git a/tests/multinode.rs b/tests/multinode.rs index c739216c3..fbe63b49c 100644 --- a/tests/multinode.rs +++ b/tests/multinode.rs @@ -10,7 +10,6 @@ use solana::entry::{reconstruct_entries_from_blobs, Entry}; use solana::fullnode::{Fullnode, FullnodeReturnType}; use solana::gossip_service::GossipService; use solana::leader_scheduler::{make_active_set_entries, LeaderScheduler, LeaderSchedulerConfig}; -use solana::mint::Mint; use solana::packet::SharedBlob; use solana::poh_service::NUM_TICKS_PER_SECOND; use solana::result; @@ -135,7 +134,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> { let bob_pubkey = Keypair::new().pubkey(); let mut ledger_paths = Vec::new(); - let (alice, leader_ledger_path) = + let (genesis_block, alice, leader_ledger_path) = create_tmp_genesis("multi_node_ledger_window", 10_000, leader_data.id, 500); ledger_paths.push(leader_ledger_path.clone()); @@ -146,14 +145,10 @@ fn test_multi_node_ledger_window() -> result::Result<()> { // write a bunch more ledger into leader's ledger, this should populate the leader's window // and force it to respond to repair from the ledger window { - let entries = make_tiny_test_entries(alice.last_id(), 100); + let entries = make_tiny_test_entries(genesis_block.last_id(), 100); let db_ledger = DbLedger::open(&leader_ledger_path).unwrap(); db_ledger - .write_entries( - DEFAULT_SLOT_HEIGHT, - solana::mint::NUM_GENESIS_ENTRIES as u64, - &entries, - ) + .write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries) .unwrap(); } @@ -238,7 +233,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> { let bob_pubkey = Keypair::new().pubkey(); let mut ledger_paths = Vec::new(); - let (alice, genesis_ledger_path) = create_tmp_genesis( + let (_genesis_block, alice, genesis_ledger_path) = create_tmp_genesis( "multi_node_validator_catchup_from_zero", 10_000, leader_data.id, @@ -431,7 +426,7 @@ fn test_multi_node_basic() { let bob_pubkey = Keypair::new().pubkey(); let mut ledger_paths = Vec::new(); - let (alice, genesis_ledger_path) = + let (_genesis_block, alice, genesis_ledger_path) = create_tmp_genesis("multi_node_basic", 10_000, leader_data.id, 500); ledger_paths.push(genesis_ledger_path.clone()); @@ -536,7 +531,7 @@ fn test_boot_validator_from_file() -> result::Result<()> { let bob_pubkey = Keypair::new().pubkey(); let mut ledger_paths = Vec::new(); - let (alice, genesis_ledger_path) = + let (_genesis_block, alice, genesis_ledger_path) = create_tmp_genesis("boot_validator_from_file", 100_000, leader_pubkey, 1000); ledger_paths.push(genesis_ledger_path.clone()); @@ -621,7 +616,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> { let leader_keypair = Arc::new(Keypair::new()); let initial_leader_balance = 500; - let (alice, ledger_path) = create_tmp_genesis( + let (_genesis_block, alice, ledger_path) = create_tmp_genesis( "leader_restart_validator_start_from_old_ledger", 100_000 + 500 * solana::window_service::MAX_REPAIR_BACKOFF as u64, leader_keypair.pubkey(), @@ -732,7 +727,7 @@ fn test_multi_node_dynamic_network() { let leader_pubkey = leader_keypair.pubkey().clone(); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let bob_pubkey = Keypair::new().pubkey(); - let (alice, genesis_ledger_path) = + let (_genesis_block, alice, genesis_ledger_path) = create_tmp_genesis("multi_node_dynamic_network", 10_000_000, leader_pubkey, 500); let mut ledger_paths = Vec::new(); @@ -857,12 +852,7 @@ fn test_multi_node_dynamic_network() { debug!("last_id: {}", last_id); trace!("Executing leader transfer of 100"); let sig = client - .transfer( - 100, - &alice_arc.read().unwrap().keypair(), - bob_pubkey, - &last_id, - ) + .transfer(100, &alice_arc.read().unwrap(), bob_pubkey, &last_id) .unwrap(); expected_balance += 100; @@ -962,13 +952,14 @@ fn test_leader_to_validator_transition() { // Initialize the leader ledger. Make a mint and a genesis entry // in the leader ledger let num_ending_ticks = 1; - let (mint, leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_leader_to_validator_transition", - 10_000, - num_ending_ticks, - leader_info.id, - 500, - ); + let (_genesis_block, mint_keypair, leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_leader_to_validator_transition", + 10_000, + num_ending_ticks, + leader_info.id, + 500, + ); let last_id = genesis_entries .last() @@ -978,7 +969,7 @@ fn test_leader_to_validator_transition() { // Write the bootstrap entries to the ledger that will cause leader rotation // after the bootstrap height let (bootstrap_entries, _) = - make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&validator_keypair, &mint_keypair, &last_id, &last_id, 0); { let db_ledger = DbLedger::open(&leader_ledger_path).unwrap(); db_ledger @@ -1040,8 +1031,13 @@ fn test_leader_to_validator_transition() { // Poll to see that the bank state is updated after every transaction // to ensure that each transaction is packaged as a single entry, // so that we can be sure leader rotation is triggered - let result = - send_tx_and_retry_get_balance(&leader_info, &mint, &bob_pubkey, 1, Some(i as u64)); + let result = send_tx_and_retry_get_balance( + &leader_info, + &mint_keypair, + &bob_pubkey, + 1, + Some(i as u64), + ); // If the transaction wasn't reflected in the node, then we assume // the node has transitioned already @@ -1102,13 +1098,14 @@ fn test_leader_validator_basic() { // Make a common mint and a genesis entry for both leader + validator ledgers let num_ending_ticks = 1; - let (mint, leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_leader_validator_basic", - 10_000, - num_ending_ticks, - leader_info.id, - 500, - ); + let (_genesis_block, mint_keypair, leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_leader_validator_basic", + 10_000, + num_ending_ticks, + leader_info.id, + 500, + ); let validator_ledger_path = tmp_copy_ledger(&leader_ledger_path, "test_leader_validator_basic"); @@ -1125,7 +1122,7 @@ fn test_leader_validator_basic() { // Write the bootstrap entries to the ledger that will cause leader rotation // after the bootstrap height let (active_set_entries, _vote_account_keypair) = - make_active_set_entries(&validator_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&validator_keypair, &mint_keypair, &last_id, &last_id, 0); { let db_ledger = DbLedger::open(&leader_ledger_path).unwrap(); db_ledger @@ -1184,7 +1181,8 @@ fn test_leader_validator_basic() { // Poll to see that the bank state is updated after every transaction // to ensure that each transaction is packaged as a single entry, // so that we can be sure leader rotation is triggered - let result = send_tx_and_retry_get_balance(&leader_info, &mint, &bob_pubkey, 1, None); + let result = + send_tx_and_retry_get_balance(&leader_info, &mint_keypair, &bob_pubkey, 1, None); // If the transaction wasn't reflected in the node, then we assume // the node has transitioned already @@ -1284,13 +1282,14 @@ fn test_dropped_handoff_recovery() { // Make a common mint and a genesis entry for both leader + validator's ledgers let num_ending_ticks = 1; - let (mint, genesis_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_dropped_handoff_recovery", - 10_000, - num_ending_ticks, - bootstrap_leader_info.id, - 500, - ); + let (_genesis_block, mint_keypair, genesis_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_dropped_handoff_recovery", + 10_000, + num_ending_ticks, + bootstrap_leader_info.id, + 500, + ); let last_id = genesis_entries .last() @@ -1309,7 +1308,7 @@ fn test_dropped_handoff_recovery() { // Make the entries to give the next_leader validator some stake so that they will be in // leader election active set let (active_set_entries, _vote_account_keypair) = - make_active_set_entries(&next_leader_keypair, &mint.keypair(), &last_id, &last_id, 0); + make_active_set_entries(&next_leader_keypair, &mint_keypair, &last_id, &last_id, 0); // Write the entries { @@ -1458,13 +1457,14 @@ fn test_full_leader_validator_network() { // Make a common mint and a genesis entry for both leader + validator's ledgers let num_ending_ticks = 1; - let (mint, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_full_leader_validator_network", - 10_000, - num_ending_ticks, - bootstrap_leader_info.id, - 500, - ); + let (_genesis_block, mint_keypair, bootstrap_leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_full_leader_validator_network", + 10_000, + num_ending_ticks, + bootstrap_leader_info.id, + 500, + ); let last_tick_id = genesis_entries .last() @@ -1491,7 +1491,7 @@ fn test_full_leader_validator_network() { // leader election active set let (bootstrap_entries, vote_account_keypair) = make_active_set_entries( node_keypair, - &mint.keypair(), + &mint_keypair, &last_entry_id, &last_tick_id, 0, @@ -1711,20 +1711,22 @@ fn test_broadcast_last_tick() { let bootstrap_leader_info = bootstrap_leader_node.info.clone(); // Create leader ledger - let (_, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger( - "test_broadcast_last_tick", - 10_000, - 0, - bootstrap_leader_info.id, - 500, - ); + let (_genesis_block, _mint_keypair, bootstrap_leader_ledger_path, genesis_entries) = + create_tmp_sample_ledger( + "test_broadcast_last_tick", + 10_000, + 1, + bootstrap_leader_info.id, + 500, + ); let num_ending_ticks = genesis_entries .iter() - .skip(2) .fold(0, |tick_count, entry| tick_count + entry.is_tick() as u64); let genesis_ledger_len = genesis_entries.len() as u64 - num_ending_ticks; + debug!("num_ending_ticks: {}", num_ending_ticks); + debug!("genesis_ledger_len: {}", genesis_ledger_len); let blob_receiver_exit = Arc::new(AtomicBool::new(false)); // Create the listeners @@ -1786,21 +1788,25 @@ fn test_broadcast_last_tick() { let last_tick_entry_height = genesis_ledger_len as u64 + bootstrap_height; let entries = read_ledger(&bootstrap_leader_ledger_path); assert!(entries.len() >= last_tick_entry_height as usize); - let expected_last_tick = &entries[last_tick_entry_height as usize - 1]; + let expected_last_tick = &entries[last_tick_entry_height as usize - 2]; + debug!("last_tick_entry_height: {:?}", last_tick_entry_height); + debug!("expected_last_tick: {:?}", expected_last_tick); info!("Check that the nodes got the last broadcasted blob"); for (_, receiver) in blob_fetch_stages.iter() { + info!("Checking a node..."); let mut last_tick_blob: SharedBlob = SharedBlob::default(); while let Ok(new_blobs) = receiver.try_recv() { let last_blob = new_blobs.into_iter().find(|b| { b.read().unwrap().index().expect("Expected index in blob") - == last_tick_entry_height - 1 + == last_tick_entry_height - 2 }); if let Some(last_blob) = last_blob { last_tick_blob = last_blob; break; } } + debug!("last_tick_blob: {:?}", last_tick_blob); let actual_last_tick = &reconstruct_entries_from_blobs(vec![&*last_tick_blob.read().unwrap()]) .expect("Expected to be able to reconstruct entries from blob") @@ -1831,7 +1837,7 @@ fn mk_client(leader: &NodeInfo) -> ThinClient { fn send_tx_and_retry_get_balance( leader: &NodeInfo, - alice: &Mint, + alice: &Keypair, bob_pubkey: &Pubkey, transfer_amount: u64, expected: Option, @@ -1839,20 +1845,20 @@ fn send_tx_and_retry_get_balance( let mut client = mk_client(leader); trace!("getting leader last_id"); let last_id = client.get_last_id(); - let mut tx = Transaction::system_new(&alice.keypair(), *bob_pubkey, transfer_amount, last_id); + let mut tx = Transaction::system_new(&alice, *bob_pubkey, transfer_amount, last_id); info!( "executing transfer of {} from {} to {}", transfer_amount, - alice.keypair().pubkey(), + alice.pubkey(), *bob_pubkey ); - let _res = client.retry_transfer(&alice.keypair(), &mut tx, 30); + let _res = client.retry_transfer(&alice, &mut tx, 30); retry_get_balance(&mut client, bob_pubkey, expected) } fn retry_send_tx_and_retry_get_balance( leader: &NodeInfo, - alice: &Mint, + alice: &Keypair, bob_pubkey: &Pubkey, expected: Option, ) -> Option { @@ -1862,9 +1868,7 @@ fn retry_send_tx_and_retry_get_balance( info!("executing leader transfer"); const LAST: usize = 30; for run in 0..(LAST + 1) { - let _sig = client - .transfer(500, &alice.keypair(), *bob_pubkey, &last_id) - .unwrap(); + let _sig = client.transfer(500, &alice, *bob_pubkey, &last_id).unwrap(); let out = client.poll_get_balance(bob_pubkey); if expected.is_none() || run == LAST { return out.ok().clone(); diff --git a/tests/programs.rs b/tests/programs.rs index 036272cd2..d886f09e5 100644 --- a/tests/programs.rs +++ b/tests/programs.rs @@ -2,7 +2,7 @@ use solana; use solana_native_loader; use solana::bank::Bank; -use solana::mint::Mint; +use solana::genesis_block::GenesisBlock; use solana::status_deque::Status; #[cfg(feature = "bpf_c")] use solana_sdk::bpf_loader; @@ -46,23 +46,24 @@ fn check_tx_results(bank: &Bank, tx: &Transaction, result: Vec Self { - let mint = Mint::new(50); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(50); + let bank = Bank::new(&genesis_block); let loader = Keypair::new(); // allocate, populate, finalize, and spawn loader let tx = Transaction::system_create( - &mint.keypair(), + &mint_keypair, loader.pubkey(), - mint.last_id(), + genesis_block.last_id(), 1, 56, // TODO solana_native_loader::id(), @@ -76,40 +77,55 @@ impl Loader { solana_native_loader::id(), 0, name.as_bytes().to_vec(), - mint.last_id(), + genesis_block.last_id(), 0, ); check_tx_results(&bank, &tx, bank.process_transactions(&vec![tx.clone()])); - let tx = - Transaction::loader_finalize(&loader, solana_native_loader::id(), mint.last_id(), 0); + let tx = Transaction::loader_finalize( + &loader, + solana_native_loader::id(), + genesis_block.last_id(), + 0, + ); check_tx_results(&bank, &tx, bank.process_transactions(&vec![tx.clone()])); - let tx = Transaction::system_spawn(&loader, mint.last_id(), 0); + let tx = Transaction::system_spawn(&loader, genesis_block.last_id(), 0); check_tx_results(&bank, &tx, bank.process_transactions(&vec![tx.clone()])); Loader { - mint, + genesis_block, + mint_keypair, bank, loader: loader.pubkey(), } } pub fn new_native() -> Self { - let mint = Mint::new(50); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(50); + let bank = Bank::new(&genesis_block); let loader = solana_native_loader::id(); - Loader { mint, bank, loader } + Loader { + genesis_block, + mint_keypair, + bank, + loader, + } } #[cfg(feature = "bpf_c")] pub fn new_bpf() -> Self { - let mint = Mint::new(50); - let bank = Bank::new(&mint); + let (genesis_block, mint_keypair) = GenesisBlock::new(50); + let bank = Bank::new(&genesis_block); let loader = bpf_loader::id(); - Loader { mint, bank, loader } + Loader { + genesis_block, + mint_keypair, + bank, + loader, + } } } @@ -124,9 +140,9 @@ impl Program { // allocate, populate, finalize and spawn program let tx = Transaction::system_create( - &loader.mint.keypair(), + &loader.mint_keypair, program.pubkey(), - loader.mint.last_id(), + loader.genesis_block.last_id(), 1, userdata.len() as u64, loader.loader, @@ -146,7 +162,7 @@ impl Program { loader.loader, offset, chunk.to_vec(), - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( @@ -157,14 +173,19 @@ impl Program { offset += chunk_size as u32; } - let tx = Transaction::loader_finalize(&program, loader.loader, loader.mint.last_id(), 0); + let tx = Transaction::loader_finalize( + &program, + loader.loader, + loader.genesis_block.last_id(), + 0, + ); check_tx_results( &loader.bank, &tx, loader.bank.process_transactions(&vec![tx.clone()]), ); - let tx = Transaction::system_spawn(&program, loader.mint.last_id(), 0); + let tx = Transaction::system_spawn(&program, loader.genesis_block.last_id(), 0); check_tx_results( &loader.bank, &tx, @@ -186,11 +207,11 @@ fn test_program_native_noop() { // Call user program let tx = Transaction::new( - &loader.mint.keypair(), + &loader.mint_keypair, &[], program.program.pubkey(), &1u8, - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( @@ -220,9 +241,9 @@ fn test_program_lua_move_funds() { // Call user program with two accounts let tx = Transaction::system_create( - &loader.mint.keypair(), + &loader.mint_keypair, from.pubkey(), - loader.mint.last_id(), + loader.genesis_block.last_id(), 10, 0, program.program.pubkey(), @@ -235,9 +256,9 @@ fn test_program_lua_move_funds() { ); let tx = Transaction::system_create( - &loader.mint.keypair(), + &loader.mint_keypair, to, - loader.mint.last_id(), + loader.genesis_block.last_id(), 1, 0, program.program.pubkey(), @@ -254,7 +275,7 @@ fn test_program_lua_move_funds() { &[to], program.program.pubkey(), &10, - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( @@ -280,11 +301,11 @@ fn test_program_builtin_bpf_noop() { // Call user program let tx = Transaction::new( - &loader.mint.keypair(), + &loader.mint_keypair, &[], program.program.pubkey(), &vec![1u8], - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( @@ -319,11 +340,11 @@ fn test_program_bpf_c() { // Call user program let tx = Transaction::new( - &loader.mint.keypair(), + &loader.mint_keypair, &[], program.program.pubkey(), &vec![1u8], - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( @@ -355,11 +376,11 @@ fn test_program_bpf_rust() { // Call user program let tx = Transaction::new( - &loader.mint.keypair(), + &loader.mint_keypair, &[], program.program.pubkey(), &vec![1u8], - loader.mint.last_id(), + loader.genesis_block.last_id(), 0, ); check_tx_results( diff --git a/tests/replicator.rs b/tests/replicator.rs index 4bb1881c3..d84343efb 100644 --- a/tests/replicator.rs +++ b/tests/replicator.rs @@ -41,7 +41,7 @@ fn test_replicator_startup() { let leader_info = leader_node.info.clone(); let leader_ledger_path = "replicator_test_leader_ledger"; - let (mint, leader_ledger_path) = + let (_genesis_block, mint_keypair, leader_ledger_path) = create_tmp_genesis(leader_ledger_path, 1_000_000_000, leader_info.id, 1); let validator_ledger_path = @@ -73,7 +73,7 @@ fn test_replicator_startup() { let mut leader_client = mk_client(&leader_info); leader_client - .transfer(10, &mint.keypair(), validator_keypair.pubkey(), &last_id) + .transfer(10, &mint_keypair, validator_keypair.pubkey(), &last_id) .unwrap(); let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey()); @@ -99,7 +99,7 @@ fn test_replicator_startup() { for _ in 0..64 { let last_id = leader_client.get_last_id(); leader_client - .transfer(1, &mint.keypair(), bob.pubkey(), &last_id) + .transfer(1, &mint_keypair, bob.pubkey(), &last_id) .unwrap(); sleep(Duration::from_millis(200)); } @@ -111,14 +111,10 @@ fn test_replicator_startup() { let last_id = leader_client.get_last_id(); // Give the replicator some tokens let amount = 1; - let mut tx = Transaction::system_new( - &mint.keypair(), - replicator_keypair.pubkey(), - amount, - last_id, - ); + let mut tx = + Transaction::system_new(&mint_keypair, replicator_keypair.pubkey(), amount, last_id); leader_client - .retry_transfer(&mint.keypair(), &mut tx, 5) + .retry_transfer(&mint_keypair, &mut tx, 5) .unwrap(); info!("starting replicator node"); @@ -270,7 +266,8 @@ fn test_replicator_startup_ledger_hang() { let leader_info = leader_node.info.clone(); let leader_ledger_path = "replicator_test_leader_ledger"; - let (_, leader_ledger_path) = create_tmp_genesis(leader_ledger_path, 100, leader_info.id, 1); + let (_genesis_block, _mint_keypair, leader_ledger_path) = + create_tmp_genesis(leader_ledger_path, 100, leader_info.id, 1); let validator_ledger_path = tmp_copy_ledger(&leader_ledger_path, "replicator_test_validator_ledger"); diff --git a/tests/rpc.rs b/tests/rpc.rs index 07a986eed..f753b4d0d 100644 --- a/tests/rpc.rs +++ b/tests/rpc.rs @@ -4,10 +4,10 @@ use reqwest::header::CONTENT_TYPE; use serde_json::{json, Value}; use solana::bank::Bank; use solana::cluster_info::Node; -use solana::db_ledger::create_tmp_ledger_with_mint; +use solana::db_ledger::create_tmp_ledger; use solana::fullnode::Fullnode; +use solana::genesis_block::GenesisBlock; use solana::leader_scheduler::LeaderScheduler; -use solana::mint::Mint; use solana::rpc_request::get_rpc_request_str; use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::vote_signer_proxy::VoteSignerProxy; @@ -26,14 +26,14 @@ fn test_rpc_send_tx() { let leader_keypair = Arc::new(Keypair::new()); let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); - let alice = Mint::new(10_000_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); let leader_data = leader.info.clone(); - let ledger_path = create_tmp_ledger_with_mint("rpc_send_tx", &alice); + let ledger_path = create_tmp_ledger("rpc_send_tx", &genesis_block); let last_id = bank.last_id(); - let tx = Transaction::system_move(&alice.keypair(), bob_pubkey, 20, last_id, 0); + let tx = Transaction::system_move(&alice, bob_pubkey, 20, last_id, 0); let serial_tx = serialize(&tx).unwrap(); let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( @@ -44,17 +44,16 @@ fn test_rpc_send_tx() { let vote_account_keypair = Arc::new(Keypair::new()); let vote_signer = VoteSignerProxy::new(&vote_account_keypair, Box::new(LocalVoteSigner::default())); - let entry_height = alice.create_entries().len() as u64; + let entry_height = 0; let server = Fullnode::new_with_bank( leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, diff --git a/wallet/tests/deploy.rs b/wallet/tests/deploy.rs index bce90b401..57ad04886 100644 --- a/wallet/tests/deploy.rs +++ b/wallet/tests/deploy.rs @@ -1,10 +1,10 @@ use serde_json::{json, Value}; use solana::bank::Bank; use solana::cluster_info::Node; -use solana::db_ledger::create_tmp_ledger_with_mint; +use solana::db_ledger::create_tmp_ledger; use solana::fullnode::Fullnode; +use solana::genesis_block::GenesisBlock; use solana::leader_scheduler::LeaderScheduler; -use solana::mint::Mint; use solana::rpc_request::{RpcClient, RpcRequest, RpcRequestHandler}; use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::vote_signer_proxy::VoteSignerProxy; @@ -31,10 +31,10 @@ fn test_wallet_deploy_program() { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); + let ledger_path = create_tmp_ledger("thin_client", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -48,19 +48,18 @@ fn test_wallet_deploy_program() { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, ); let (sender, receiver) = channel(); - run_local_drone(alice.keypair(), sender); + run_local_drone(alice, sender); let drone_addr = receiver.recv().unwrap(); let rpc_client = RpcClient::new_from_socket(leader_data.rpc); diff --git a/wallet/tests/pay.rs b/wallet/tests/pay.rs index 03a4418a9..95381c795 100644 --- a/wallet/tests/pay.rs +++ b/wallet/tests/pay.rs @@ -2,10 +2,10 @@ use chrono::prelude::*; use serde_json::{json, Value}; use solana::bank::Bank; use solana::cluster_info::Node; -use solana::db_ledger::create_tmp_ledger_with_mint; +use solana::db_ledger::create_tmp_ledger; use solana::fullnode::Fullnode; +use solana::genesis_block::GenesisBlock; use solana::leader_scheduler::LeaderScheduler; -use solana::mint::Mint; use solana::rpc_request::{RpcClient, RpcRequest, RpcRequestHandler}; use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::vote_signer_proxy::VoteSignerProxy; @@ -35,11 +35,11 @@ fn test_wallet_timestamp_tx() { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let ledger_path = create_tmp_ledger("thin_client", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -53,19 +53,18 @@ fn test_wallet_timestamp_tx() { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, ); let (sender, receiver) = channel(); - run_local_drone(alice.keypair(), sender); + run_local_drone(alice, sender); let drone_addr = receiver.recv().unwrap(); let rpc_client = RpcClient::new_from_socket(leader_data.rpc); @@ -132,11 +131,11 @@ fn test_wallet_witness_tx() { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let ledger_path = create_tmp_ledger("test_wallet_witness_tx", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -150,19 +149,18 @@ fn test_wallet_witness_tx() { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, ); let (sender, receiver) = channel(); - run_local_drone(alice.keypair(), sender); + run_local_drone(alice, sender); let drone_addr = receiver.recv().unwrap(); let rpc_client = RpcClient::new_from_socket(leader_data.rpc); @@ -225,11 +223,11 @@ fn test_wallet_cancel_tx() { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); let bob_pubkey = Keypair::new().pubkey(); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let ledger_path = create_tmp_ledger("test_wallet_cancel_tx", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -243,19 +241,18 @@ fn test_wallet_cancel_tx() { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, ); let (sender, receiver) = channel(); - run_local_drone(alice.keypair(), sender); + run_local_drone(alice, sender); let drone_addr = receiver.recv().unwrap(); let rpc_client = RpcClient::new_from_socket(leader_data.rpc); diff --git a/wallet/tests/request_airdrop.rs b/wallet/tests/request_airdrop.rs index 8e6db8238..d01a175d8 100644 --- a/wallet/tests/request_airdrop.rs +++ b/wallet/tests/request_airdrop.rs @@ -1,10 +1,10 @@ use serde_json::json; use solana::bank::Bank; use solana::cluster_info::Node; -use solana::db_ledger::create_tmp_ledger_with_mint; +use solana::db_ledger::create_tmp_ledger; use solana::fullnode::Fullnode; +use solana::genesis_block::GenesisBlock; use solana::leader_scheduler::LeaderScheduler; -use solana::mint::Mint; use solana::rpc_request::{RpcClient, RpcRequest, RpcRequestHandler}; use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::vote_signer_proxy::VoteSignerProxy; @@ -22,10 +22,10 @@ fn test_wallet_request_airdrop() { let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey()); let leader_data = leader.info.clone(); - let alice = Mint::new(10_000); - let mut bank = Bank::new(&alice); - let ledger_path = create_tmp_ledger_with_mint("thin_client", &alice); - let entry_height = alice.create_entries().len() as u64; + let (genesis_block, alice) = GenesisBlock::new(10_000); + let mut bank = Bank::new(&genesis_block); + let ledger_path = create_tmp_ledger("thin_client", &genesis_block); + let entry_height = 0; let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::from_bootstrap_leader( leader_data.id, @@ -39,19 +39,18 @@ fn test_wallet_request_airdrop() { leader_keypair, Some(Arc::new(vote_signer)), bank, - None, + &ledger_path, entry_height, &last_id, leader, None, - &ledger_path, false, None, STORAGE_ROTATE_TEST_COUNT, ); let (sender, receiver) = channel(); - run_local_drone(alice.keypair(), sender); + run_local_drone(alice, sender); let drone_addr = receiver.recv().unwrap(); let mut bob_config = WalletConfig::default();