Genesis block is now a json file

This commit is contained in:
Michael Vines 2019-01-24 12:04:04 -08:00
parent 06e3cd3d2a
commit 4bb6549895
30 changed files with 924 additions and 1052 deletions

View File

@ -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.

View File

@ -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();
}

View File

@ -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

View File

@ -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<dyn error::Error>> {
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<dyn error::Error>> {
.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<dyn error::Error>> {
.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<u8> = 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(())
}

View File

@ -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() {

View File

@ -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<I>(
&self,
start_hash: Hash,
entry_height: u64,
entries: I,
) -> Result<(u64, Hash)>
pub fn process_ledger<I>(&self, entries: I) -> Result<(u64, Hash)>
where
I: IntoIterator<Item = Entry>,
{
// 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<I>(&self, entries: I) -> Result<(u64, Hash)>
where
I: IntoIterator<Item = Entry>,
{
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<Item = Entry> {
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<Entry> = 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<Item = Entry> {
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<Item = Entry>, 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<Item = Entry> {
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<Item = Entry>) {
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,
)];

View File

@ -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;

View File

@ -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)

View File

@ -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<Self> {
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<Item = &'a Entry>,
@ -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<Entry>) {
let mint = Mint::new_with_leader(num_tokens, bootstrap_leader_id, bootstrap_leader_tokens);
) -> (GenesisBlock, Keypair, String, Vec<Entry>) {
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)]

View File

@ -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<UdpSocket>,
broadcast_socket: UdpSocket,
genesis_block: GenesisBlock,
db_ledger: Arc<DbLedger>,
vote_signer: Option<Arc<VoteSignerProxy>>,
}
@ -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<Keypair>,
vote_signer: Option<Arc<VoteSignerProxy>>,
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<u16>,
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<Keypair>,
vote_signer: Option<Arc<VoteSignerProxy>>,
bank: Bank,
db_ledger: Option<Arc<DbLedger>>,
genesis_block: GenesisBlock,
db_ledger: Arc<DbLedger>,
entry_height: u64,
last_entry_id: &Hash,
mut node: Node,
entrypoint_info_option: Option<&NodeInfo>,
ledger_path: &str,
sigverify_disabled: bool,
rpc_port: Option<u16>,
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<RwLock<LeaderScheduler>>,
) -> (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<RwLock<LeaderScheduler>>,
) -> (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<RwLock<LeaderScheduler>> {
&self.bank.leader_scheduler
}
fn make_db_ledger(ledger_path: &str) -> Arc<DbLedger> {
Arc::new(
fn make_db_ledger(ledger_path: &str) -> (GenesisBlock, Arc<DbLedger>) {
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))),
);

92
src/genesis_block.rs Normal file
View File

@ -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<Self, std::io::Error> {
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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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<u8>,
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<u8>,
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<Transaction> {
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<Entry> {
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));
}
}

View File

@ -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));

View File

@ -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);

View File

@ -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);
}

View File

@ -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>, 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;

View File

@ -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();

View File

@ -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,

View File

@ -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());

View File

@ -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());

View File

@ -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);

View File

@ -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<u64>,
@ -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<u64>,
) -> Option<u64> {
@ -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();

View File

@ -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<solana::bank::Res
}
struct Loader {
mint: Mint,
genesis_block: GenesisBlock,
mint_keypair: Keypair,
bank: Bank,
loader: Pubkey,
}
impl Loader {
pub fn new_dynamic(loader_name: &str) -> 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(

View File

@ -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");

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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();