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