Add first leader to genesis (#1681)
* Add first leader to genesis entries, consume in genesis.sh * Set bootstrap leader in the bank on startup, remove instantiation of bootstrap leader from bin/fullnode * Remove need to initialize bootstrap leader in leader_scheduler, now can be read from genesis entries * Add separate interface new_with_leader() in mint for creating genesis leader entries
This commit is contained in:
parent
a8481215fa
commit
298bd6479a
|
@ -14,7 +14,7 @@ use solana::entry::Entry;
|
||||||
use solana::hash::hash;
|
use solana::hash::hash;
|
||||||
use solana::mint::Mint;
|
use solana::mint::Mint;
|
||||||
use solana::packet::to_packets_chunked;
|
use solana::packet::to_packets_chunked;
|
||||||
use solana::signature::{KeypairUtil, Signature};
|
use solana::signature::{Keypair, KeypairUtil, Signature};
|
||||||
use solana::system_transaction::SystemTransaction;
|
use solana::system_transaction::SystemTransaction;
|
||||||
use solana::transaction::Transaction;
|
use solana::transaction::Transaction;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
@ -78,7 +78,8 @@ fn bench_banking_stage_multi_accounts(bencher: &mut Bencher) {
|
||||||
mint.last_id(),
|
mint.last_id(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
assert!(bank.process_transaction(&fund).is_ok());
|
let x = bank.process_transaction(&fund);
|
||||||
|
assert!(x.is_ok());
|
||||||
});
|
});
|
||||||
//sanity check, make sure all the transactions can execute sequentially
|
//sanity check, make sure all the transactions can execute sequentially
|
||||||
transactions.iter().for_each(|tx| {
|
transactions.iter().for_each(|tx| {
|
||||||
|
|
|
@ -6,8 +6,8 @@ export RUST_BACKTRACE=1
|
||||||
solana-keygen -o /config/leader-keypair.json
|
solana-keygen -o /config/leader-keypair.json
|
||||||
solana-keygen -o /config/drone-keypair.json
|
solana-keygen -o /config/drone-keypair.json
|
||||||
|
|
||||||
solana-genesis --tokens=1000000000 --ledger /ledger < /config/drone-keypair.json
|
|
||||||
solana-fullnode-config --keypair=/config/leader-keypair.json -l > /config/leader-config.json
|
solana-fullnode-config --keypair=/config/leader-keypair.json -l > /config/leader-config.json
|
||||||
|
solana-genesis --tokens=1000000000 --mint /config/drone-keypair.json --bootstrap_leader /config/leader-config.json --ledger /ledger
|
||||||
|
|
||||||
solana-drone --keypair /config/drone-keypair.json --network 127.0.0.1:8001 &
|
solana-drone --keypair /config/drone-keypair.json --network 127.0.0.1:8001 &
|
||||||
drone=$!
|
drone=$!
|
||||||
|
|
|
@ -104,11 +104,11 @@ if $node_type_leader; then
|
||||||
echo "Creating $mint_path with $num_tokens tokens"
|
echo "Creating $mint_path with $num_tokens tokens"
|
||||||
$solana_keygen -o "$mint_path"
|
$solana_keygen -o "$mint_path"
|
||||||
|
|
||||||
echo "Creating $SOLANA_CONFIG_DIR/ledger"
|
|
||||||
$solana_genesis --tokens="$num_tokens" --ledger "$SOLANA_CONFIG_DIR"/ledger < "$mint_path"
|
|
||||||
|
|
||||||
echo "Creating $SOLANA_CONFIG_DIR/leader.json"
|
echo "Creating $SOLANA_CONFIG_DIR/leader.json"
|
||||||
$solana_fullnode_config --keypair="$leader_id_path" "${leader_address_args[@]}" > "$SOLANA_CONFIG_DIR"/leader.json
|
$solana_fullnode_config --keypair="$leader_id_path" "${leader_address_args[@]}" > "$SOLANA_CONFIG_DIR"/leader.json
|
||||||
|
|
||||||
|
echo "Creating $SOLANA_CONFIG_DIR/ledger"
|
||||||
|
$solana_genesis --num_tokens "$num_tokens" --mint "$mint_path" --bootstrap_leader "$SOLANA_CONFIG_DIR"/leader.json --ledger "$SOLANA_CONFIG_DIR"/ledger
|
||||||
|
|
||||||
ls -lhR "$SOLANA_CONFIG_DIR"/
|
ls -lhR "$SOLANA_CONFIG_DIR"/
|
||||||
ls -lhR "$SOLANA_CONFIG_PRIVATE_DIR"/
|
ls -lhR "$SOLANA_CONFIG_PRIVATE_DIR"/
|
||||||
|
|
|
@ -120,9 +120,11 @@ pub extern "C" fn process(keyed_accounts: &mut [KeyedAccount], tx_data: &[u8]) -
|
||||||
};
|
};
|
||||||
let mut v = serialize_parameters(&mut keyed_accounts[1..], &tx_data);
|
let mut v = serialize_parameters(&mut keyed_accounts[1..], &tx_data);
|
||||||
match vm.execute_program(v.as_mut_slice()) {
|
match vm.execute_program(v.as_mut_slice()) {
|
||||||
Ok(status) => if 0 == status {
|
Ok(status) => {
|
||||||
return false;
|
if 0 == status {
|
||||||
},
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("execute_program failed: {}", e);
|
warn!("execute_program failed: {}", e);
|
||||||
return false;
|
return false;
|
||||||
|
|
134
src/bank.rs
134
src/bank.rs
|
@ -202,9 +202,9 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an Bank using a deposit.
|
/// Create an Bank using a deposit.
|
||||||
pub fn new_from_deposit(deposit: &Payment) -> Self {
|
pub fn new_from_deposits(deposits: &[Payment]) -> Self {
|
||||||
let bank = Self::default();
|
let bank = Self::default();
|
||||||
{
|
for deposit in deposits {
|
||||||
let mut accounts = bank.accounts.write().unwrap();
|
let mut accounts = bank.accounts.write().unwrap();
|
||||||
let account = accounts.entry(deposit.to).or_insert_with(Account::default);
|
let account = accounts.entry(deposit.to).or_insert_with(Account::default);
|
||||||
Self::apply_payment(deposit, account);
|
Self::apply_payment(deposit, account);
|
||||||
|
@ -215,11 +215,28 @@ impl Bank {
|
||||||
|
|
||||||
/// Create an Bank with only a Mint. Typically used by unit tests.
|
/// Create an Bank with only a Mint. Typically used by unit tests.
|
||||||
pub fn new(mint: &Mint) -> Self {
|
pub fn new(mint: &Mint) -> Self {
|
||||||
let deposit = Payment {
|
let mint_tokens = if mint.bootstrap_leader_id != Pubkey::default() {
|
||||||
to: mint.pubkey(),
|
mint.tokens - mint.bootstrap_leader_tokens
|
||||||
tokens: mint.tokens,
|
} else {
|
||||||
|
mint.tokens
|
||||||
};
|
};
|
||||||
let bank = Self::new_from_deposit(&deposit);
|
|
||||||
|
let mint_deposit = Payment {
|
||||||
|
to: mint.pubkey(),
|
||||||
|
tokens: mint_tokens,
|
||||||
|
};
|
||||||
|
|
||||||
|
let deposits = if mint.bootstrap_leader_id != Pubkey::default() {
|
||||||
|
let leader_deposit = Payment {
|
||||||
|
to: mint.bootstrap_leader_id,
|
||||||
|
tokens: mint.bootstrap_leader_tokens,
|
||||||
|
};
|
||||||
|
vec![mint_deposit, leader_deposit]
|
||||||
|
} else {
|
||||||
|
vec![mint_deposit]
|
||||||
|
};
|
||||||
|
|
||||||
|
let bank = Self::new_from_deposits(&deposits);
|
||||||
bank.register_entry_id(&mint.last_id());
|
bank.register_entry_id(&mint.last_id());
|
||||||
bank
|
bank
|
||||||
}
|
}
|
||||||
|
@ -416,9 +433,11 @@ impl Bank {
|
||||||
fn unlock_account(tx: &Transaction, result: &Result<()>, account_locks: &mut HashSet<Pubkey>) {
|
fn unlock_account(tx: &Transaction, result: &Result<()>, account_locks: &mut HashSet<Pubkey>) {
|
||||||
match result {
|
match result {
|
||||||
Err(BankError::AccountInUse) => (),
|
Err(BankError::AccountInUse) => (),
|
||||||
_ => for k in &tx.account_keys {
|
_ => {
|
||||||
account_locks.remove(k);
|
for k in &tx.account_keys {
|
||||||
},
|
account_locks.remove(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,28 +1045,70 @@ impl Bank {
|
||||||
// which implies its id can be used as the ledger's seed.
|
// which implies its id can be used as the ledger's seed.
|
||||||
let entry0 = entries.next().expect("invalid ledger: empty");
|
let entry0 = entries.next().expect("invalid ledger: empty");
|
||||||
|
|
||||||
// The second item in the ledger is a special transaction where the to and from
|
// 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
|
// fields are the same. That entry should be treated as a deposit, not a
|
||||||
// transfer to oneself.
|
// 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
|
let entry1 = entries
|
||||||
.next()
|
.next()
|
||||||
.expect("invalid ledger: need at least 2 entries");
|
.expect("invalid ledger: need at least 2 entries");
|
||||||
{
|
{
|
||||||
|
// Process the first transaction
|
||||||
let tx = &entry1.transactions[0];
|
let tx = &entry1.transactions[0];
|
||||||
assert!(SystemProgram::check_id(tx.program_id(0)), "Invalid ledger");
|
assert!(SystemProgram::check_id(tx.program_id(0)), "Invalid ledger");
|
||||||
let instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
|
assert!(SystemProgram::check_id(tx.program_id(1)), "Invalid ledger");
|
||||||
let deposit = if let SystemProgram::Move { tokens } = instruction {
|
let mut instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
|
||||||
|
let mint_deposit = if let SystemProgram::Move { tokens } = instruction {
|
||||||
Some(tokens)
|
Some(tokens)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}.expect("invalid ledger, needs to start with a contract");
|
}.expect("invalid ledger, needs to start with mint deposit");
|
||||||
|
|
||||||
|
instruction = deserialize(tx.userdata(1)).unwrap();
|
||||||
|
let leader_payment = if let SystemProgram::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 accounts = self.accounts.write().unwrap();
|
let mut accounts = self.accounts.write().unwrap();
|
||||||
|
{
|
||||||
|
let account = accounts
|
||||||
|
.entry(tx.account_keys[0])
|
||||||
|
.or_insert_with(Account::default);
|
||||||
|
account.tokens += mint_deposit - leader_payment;
|
||||||
|
trace!(
|
||||||
|
"applied genesis payment to mint {:?} => {:?}",
|
||||||
|
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 trnsaction and the first move instruction is to the 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 account = accounts
|
let account = accounts
|
||||||
.entry(tx.account_keys[0])
|
.entry(bootstrap_leader_id)
|
||||||
.or_insert_with(Account::default);
|
.or_insert_with(Account::default);
|
||||||
account.tokens += deposit;
|
account.tokens += leader_payment;
|
||||||
trace!("applied genesis payment {:?} => {:?}", deposit, account);
|
self.leader_scheduler.write().unwrap().bootstrap_leader = bootstrap_leader_id;
|
||||||
|
trace!(
|
||||||
|
"applied genesis payment to bootstrap leader {:?} => {:?}",
|
||||||
|
leader_payment,
|
||||||
|
account
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.register_entry_id(&entry0.id);
|
self.register_entry_id(&entry0.id);
|
||||||
|
@ -1261,6 +1322,16 @@ mod tests {
|
||||||
assert_eq!(bank.get_balance(&mint.pubkey()), 10_000);
|
assert_eq!(bank.get_balance(&mint.pubkey()), 10_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bank_new_with_leader() {
|
||||||
|
let dummy_leader_id = Keypair::new().pubkey();
|
||||||
|
let dummy_leader_tokens = 1;
|
||||||
|
let mint = Mint::new_with_leader(10_000, dummy_leader_id, dummy_leader_tokens);
|
||||||
|
let bank = Bank::new(&mint);
|
||||||
|
assert_eq!(bank.get_balance(&mint.pubkey()), 9999);
|
||||||
|
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 mint = Mint::new(10_000);
|
||||||
|
@ -1573,11 +1644,18 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process_genesis() {
|
fn test_process_genesis() {
|
||||||
let mint = Mint::new(1);
|
let dummy_leader_id = Keypair::new().pubkey();
|
||||||
|
let dummy_leader_tokens = 1;
|
||||||
|
let mint = Mint::new_with_leader(5, dummy_leader_id, dummy_leader_tokens);
|
||||||
let genesis = mint.create_entries();
|
let genesis = mint.create_entries();
|
||||||
let bank = Bank::default();
|
let bank = Bank::default();
|
||||||
bank.process_ledger(genesis).unwrap();
|
bank.process_ledger(genesis).unwrap();
|
||||||
assert_eq!(bank.get_balance(&mint.pubkey()), 1);
|
assert_eq!(bank.get_balance(&mint.pubkey()), 4);
|
||||||
|
assert_eq!(bank.get_balance(&dummy_leader_id), 1);
|
||||||
|
assert_eq!(
|
||||||
|
bank.leader_scheduler.read().unwrap().bootstrap_leader,
|
||||||
|
dummy_leader_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_sample_block_with_next_entries_using_keypairs(
|
fn create_sample_block_with_next_entries_using_keypairs(
|
||||||
|
@ -1633,7 +1711,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_sample_ledger(length: usize) -> (impl Iterator<Item = Entry>, Pubkey) {
|
fn create_sample_ledger(length: usize) -> (impl Iterator<Item = Entry>, Pubkey) {
|
||||||
let mint = Mint::new(length as i64 + 1);
|
let dummy_leader_id = Keypair::new().pubkey();
|
||||||
|
let dummy_leader_tokens = 1;
|
||||||
|
let mint = Mint::new_with_leader(
|
||||||
|
length as i64 + 1 + dummy_leader_tokens,
|
||||||
|
dummy_leader_id,
|
||||||
|
dummy_leader_tokens,
|
||||||
|
);
|
||||||
let genesis = mint.create_entries();
|
let genesis = mint.create_entries();
|
||||||
let block = create_sample_block_with_ticks(&mint, length, length);
|
let block = create_sample_block_with_ticks(&mint, length, length);
|
||||||
(genesis.into_iter().chain(block), mint.pubkey())
|
(genesis.into_iter().chain(block), mint.pubkey())
|
||||||
|
@ -1681,18 +1765,24 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process_ledger_from_files() {
|
fn test_process_ledger_from_files() {
|
||||||
let mint = Mint::new(2);
|
let dummy_leader_id = Keypair::new().pubkey();
|
||||||
|
let dummy_leader_tokens = 1;
|
||||||
|
let mint = Mint::new_with_leader(2, dummy_leader_id, dummy_leader_tokens);
|
||||||
|
|
||||||
let genesis = to_file_iter(mint.create_entries().into_iter());
|
let genesis = to_file_iter(mint.create_entries().into_iter());
|
||||||
let block = to_file_iter(create_sample_block_with_ticks(&mint, 1, 1));
|
let block = to_file_iter(create_sample_block_with_ticks(&mint, 1, 1));
|
||||||
|
|
||||||
let bank = Bank::default();
|
let bank = Bank::default();
|
||||||
bank.process_ledger(genesis.chain(block)).unwrap();
|
bank.process_ledger(genesis.chain(block)).unwrap();
|
||||||
assert_eq!(bank.get_balance(&mint.pubkey()), 1);
|
assert_eq!(bank.get_balance(&mint.pubkey()), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hash_internal_state() {
|
fn test_hash_internal_state() {
|
||||||
let mint = Mint::new(2_000);
|
let dummy_leader_id = Keypair::new().pubkey();
|
||||||
|
let dummy_leader_tokens = 1;
|
||||||
|
let mint = Mint::new_with_leader(2_000, dummy_leader_id, dummy_leader_tokens);
|
||||||
|
|
||||||
let 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);
|
||||||
|
|
|
@ -182,11 +182,13 @@ impl BankingStage {
|
||||||
.zip(vers)
|
.zip(vers)
|
||||||
.filter_map(|(tx, ver)| match tx {
|
.filter_map(|(tx, ver)| match tx {
|
||||||
None => None,
|
None => None,
|
||||||
Some((tx, _addr)) => if tx.verify_refs() && ver != 0 {
|
Some((tx, _addr)) => {
|
||||||
Some(tx)
|
if tx.verify_refs() && ver != 0 {
|
||||||
} else {
|
Some(tx)
|
||||||
None
|
} else {
|
||||||
},
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
debug!("verified transactions {}", transactions.len());
|
debug!("verified transactions {}", transactions.len());
|
||||||
Self::process_transactions(bank, &transactions, poh)?;
|
Self::process_transactions(bank, &transactions, poh)?;
|
||||||
|
|
|
@ -97,6 +97,11 @@ fn main() {
|
||||||
let keypair = Arc::new(keypair);
|
let keypair = Arc::new(keypair);
|
||||||
let pubkey = keypair.pubkey();
|
let pubkey = keypair.pubkey();
|
||||||
|
|
||||||
|
let mut leader_scheduler = LeaderScheduler::default();
|
||||||
|
|
||||||
|
// Remove this line to enable leader rotation
|
||||||
|
leader_scheduler.use_only_bootstrap_leader = true;
|
||||||
|
|
||||||
let mut fullnode = Fullnode::new(
|
let mut fullnode = Fullnode::new(
|
||||||
node,
|
node,
|
||||||
ledger_path,
|
ledger_path,
|
||||||
|
@ -104,7 +109,7 @@ fn main() {
|
||||||
vote_account_keypair,
|
vote_account_keypair,
|
||||||
network,
|
network,
|
||||||
false,
|
false,
|
||||||
LeaderScheduler::from_bootstrap_leader(leader.id),
|
leader_scheduler,
|
||||||
);
|
);
|
||||||
let mut client = mk_client(&leader);
|
let mut client = mk_client(&leader);
|
||||||
|
|
||||||
|
|
|
@ -5,26 +5,44 @@ extern crate atty;
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate solana;
|
extern crate solana;
|
||||||
|
extern crate untrusted;
|
||||||
|
|
||||||
use atty::{is, Stream};
|
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
use solana::fullnode::Config;
|
||||||
use solana::ledger::LedgerWriter;
|
use solana::ledger::LedgerWriter;
|
||||||
use solana::mint::Mint;
|
use solana::mint::Mint;
|
||||||
|
use solana::signature::KeypairUtil;
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::io::{stdin, Read};
|
use std::fs::File;
|
||||||
use std::process::exit;
|
use std::path::Path;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<error::Error>> {
|
fn main() -> Result<(), Box<error::Error>> {
|
||||||
let matches = App::new("solana-genesis")
|
let matches = App::new("solana-genesis")
|
||||||
.version(crate_version!())
|
.version(crate_version!())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("tokens")
|
Arg::with_name("num_tokens")
|
||||||
.short("t")
|
.short("t")
|
||||||
.long("tokens")
|
.long("num_tokens")
|
||||||
.value_name("NUM")
|
.value_name("TOKENS")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(true)
|
.required(true)
|
||||||
.help("Number of tokens with which to initialize mint"),
|
.help("Number of tokens to create in the mint"),
|
||||||
|
).arg(
|
||||||
|
Arg::with_name("mint")
|
||||||
|
.short("m")
|
||||||
|
.long("mint")
|
||||||
|
.value_name("MINT")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)
|
||||||
|
.help("Path to file containing keys of the mint"),
|
||||||
|
).arg(
|
||||||
|
Arg::with_name("bootstrap_leader")
|
||||||
|
.short("b")
|
||||||
|
.long("bootstrap_leader")
|
||||||
|
.value_name("BOOTSTRAP LEADER")
|
||||||
|
.takes_value(true)
|
||||||
|
.required(true)
|
||||||
|
.help("Path to file containing keys of the bootstrap leader"),
|
||||||
).arg(
|
).arg(
|
||||||
Arg::with_name("ledger")
|
Arg::with_name("ledger")
|
||||||
.short("l")
|
.short("l")
|
||||||
|
@ -35,24 +53,19 @@ fn main() -> Result<(), Box<error::Error>> {
|
||||||
.help("Use directory as persistent ledger location"),
|
.help("Use directory as persistent ledger location"),
|
||||||
).get_matches();
|
).get_matches();
|
||||||
|
|
||||||
let tokens = value_t_or_exit!(matches, "tokens", i64);
|
// Parse the input leader configuration
|
||||||
|
let file = File::open(Path::new(&matches.value_of("bootstrap_leader").unwrap())).unwrap();
|
||||||
|
let leader_config: Config = serde_json::from_reader(file).unwrap();
|
||||||
|
let leader_keypair = leader_config.keypair();
|
||||||
|
|
||||||
|
// Parse the input mint configuration
|
||||||
|
let num_tokens = value_t_or_exit!(matches, "num_tokens", i64);
|
||||||
|
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(), 1);
|
||||||
|
|
||||||
|
// Write the ledger entries
|
||||||
let ledger_path = matches.value_of("ledger").unwrap();
|
let ledger_path = matches.value_of("ledger").unwrap();
|
||||||
|
|
||||||
if is(Stream::Stdin) {
|
|
||||||
eprintln!("nothing found on stdin, expected a json file");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut buffer = String::new();
|
|
||||||
let num_bytes = stdin().read_to_string(&mut buffer)?;
|
|
||||||
if num_bytes == 0 {
|
|
||||||
eprintln!("empty file on stdin, expected a json file");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let pkcs8: Vec<u8> = serde_json::from_str(&buffer)?;
|
|
||||||
let mint = Mint::new_with_pkcs8(tokens, pkcs8);
|
|
||||||
|
|
||||||
let mut ledger_writer = LedgerWriter::open(&ledger_path, true)?;
|
let mut ledger_writer = LedgerWriter::open(&ledger_path, true)?;
|
||||||
ledger_writer.write_entries(&mint.create_entries())?;
|
ledger_writer.write_entries(&mint.create_entries())?;
|
||||||
|
|
||||||
|
|
|
@ -1825,16 +1825,24 @@ mod tests {
|
||||||
let obj = Arc::new(RwLock::new(cluster_info));
|
let obj = Arc::new(RwLock::new(cluster_info));
|
||||||
|
|
||||||
let request = Protocol::RequestUpdates(1, node.clone());
|
let request = Protocol::RequestUpdates(1, node.clone());
|
||||||
assert!(
|
assert!(ClusterInfo::handle_protocol(
|
||||||
ClusterInfo::handle_protocol(&obj, &node.contact_info.ncp, request, &window, &mut None,)
|
&obj,
|
||||||
.is_none()
|
&node.contact_info.ncp,
|
||||||
);
|
request,
|
||||||
|
&window,
|
||||||
|
&mut None,
|
||||||
|
)
|
||||||
|
.is_none());
|
||||||
|
|
||||||
let request = Protocol::RequestUpdates(1, node_with_same_addr.clone());
|
let request = Protocol::RequestUpdates(1, node_with_same_addr.clone());
|
||||||
assert!(
|
assert!(ClusterInfo::handle_protocol(
|
||||||
ClusterInfo::handle_protocol(&obj, &node.contact_info.ncp, request, &window, &mut None,)
|
&obj,
|
||||||
.is_none()
|
&node.contact_info.ncp,
|
||||||
);
|
request,
|
||||||
|
&window,
|
||||||
|
&mut None,
|
||||||
|
)
|
||||||
|
.is_none());
|
||||||
|
|
||||||
let request = Protocol::RequestUpdates(1, node_with_diff_addr.clone());
|
let request = Protocol::RequestUpdates(1, node_with_diff_addr.clone());
|
||||||
ClusterInfo::handle_protocol(&obj, &node.contact_info.ncp, request, &window, &mut None);
|
ClusterInfo::handle_protocol(&obj, &node.contact_info.ncp, request, &window, &mut None);
|
||||||
|
|
|
@ -107,13 +107,13 @@ pub struct Fullnode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
/// Fullnode configuration to be stored in file
|
/// Fullnode configuration to be stored in file
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub node_info: NodeInfo,
|
pub node_info: NodeInfo,
|
||||||
pkcs8: Vec<u8>,
|
pkcs8: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure to be replicated by the network
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new(bind_addr: &SocketAddr, pkcs8: Vec<u8>) -> Self {
|
pub fn new(bind_addr: &SocketAddr, pkcs8: Vec<u8>) -> Self {
|
||||||
let keypair =
|
let keypair =
|
||||||
|
@ -679,7 +679,8 @@ 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) = create_tmp_genesis("validator_exit", 10_000);
|
let (mint, validator_ledger_path) =
|
||||||
|
create_tmp_genesis("validator_exit", 10_000, keypair.pubkey(), 1000);
|
||||||
let mut bank = Bank::new(&mint);
|
let mut bank = Bank::new(&mint);
|
||||||
let entry = tn.info.clone();
|
let entry = tn.info.clone();
|
||||||
let genesis_entries = &mint.create_entries();
|
let genesis_entries = &mint.create_entries();
|
||||||
|
@ -714,8 +715,12 @@ 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) =
|
let (mint, validator_ledger_path) = create_tmp_genesis(
|
||||||
create_tmp_genesis(&format!("validator_parallel_exit_{}", i), 10_000);
|
&format!("validator_parallel_exit_{}", i),
|
||||||
|
10_000,
|
||||||
|
keypair.pubkey(),
|
||||||
|
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(&mint);
|
||||||
let entry = tn.info.clone();
|
let entry = tn.info.clone();
|
||||||
|
@ -764,8 +769,13 @@ 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) =
|
let (_, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("test_leader_to_leader_transition", 10_000, num_ending_ticks);
|
"test_leader_to_leader_transition",
|
||||||
|
10_000,
|
||||||
|
num_ending_ticks,
|
||||||
|
bootstrap_leader_keypair.pubkey(),
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
|
||||||
let initial_tick_height = genesis_entries
|
let initial_tick_height = genesis_entries
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -785,7 +795,6 @@ mod tests {
|
||||||
// restart as a leader again.
|
// restart as a leader again.
|
||||||
let bootstrap_height = initial_tick_height + 1;
|
let bootstrap_height = initial_tick_height + 1;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_info.id,
|
|
||||||
Some(bootstrap_height as u64),
|
Some(bootstrap_height as u64),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -834,8 +843,13 @@ mod tests {
|
||||||
|
|
||||||
// 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) =
|
let (mint, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("test_wrong_role_transition", 10_000, num_ending_ticks);
|
"test_wrong_role_transition",
|
||||||
|
10_000,
|
||||||
|
num_ending_ticks,
|
||||||
|
bootstrap_leader_keypair.pubkey(),
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
|
||||||
let last_id = genesis_entries
|
let last_id = genesis_entries
|
||||||
.last()
|
.last()
|
||||||
|
@ -870,7 +884,6 @@ mod tests {
|
||||||
// after parsing the ledger during startup
|
// after parsing the ledger during startup
|
||||||
let bootstrap_height = genesis_tick_height;
|
let bootstrap_height = genesis_tick_height;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_info.id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -930,6 +943,8 @@ mod tests {
|
||||||
"test_validator_to_leader_transition",
|
"test_validator_to_leader_transition",
|
||||||
10_000,
|
10_000,
|
||||||
num_ending_ticks,
|
num_ending_ticks,
|
||||||
|
leader_id,
|
||||||
|
500,
|
||||||
);
|
);
|
||||||
|
|
||||||
let validator_keypair = Keypair::new();
|
let validator_keypair = Keypair::new();
|
||||||
|
@ -967,7 +982,6 @@ mod tests {
|
||||||
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(leader_rotation_interval * 2),
|
Some(leader_rotation_interval * 2),
|
||||||
|
|
|
@ -23,9 +23,6 @@ pub const DEFAULT_SEED_ROTATION_INTERVAL: u64 = 1000;
|
||||||
pub const DEFAULT_ACTIVE_WINDOW_LENGTH: u64 = 1000;
|
pub const DEFAULT_ACTIVE_WINDOW_LENGTH: u64 = 1000;
|
||||||
|
|
||||||
pub struct LeaderSchedulerConfig {
|
pub struct LeaderSchedulerConfig {
|
||||||
// The first leader who will bootstrap the network
|
|
||||||
pub bootstrap_leader: Pubkey,
|
|
||||||
|
|
||||||
// The interval at which to rotate the leader, should be much less than
|
// The interval at which to rotate the leader, should be much less than
|
||||||
// seed_rotation_interval
|
// seed_rotation_interval
|
||||||
pub leader_rotation_interval_option: Option<u64>,
|
pub leader_rotation_interval_option: Option<u64>,
|
||||||
|
@ -45,14 +42,12 @@ pub struct LeaderSchedulerConfig {
|
||||||
// need leader rotation don't break
|
// need leader rotation don't break
|
||||||
impl LeaderSchedulerConfig {
|
impl LeaderSchedulerConfig {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
bootstrap_leader: Pubkey,
|
|
||||||
bootstrap_height_option: Option<u64>,
|
bootstrap_height_option: Option<u64>,
|
||||||
leader_rotation_interval_option: Option<u64>,
|
leader_rotation_interval_option: Option<u64>,
|
||||||
seed_rotation_interval_option: Option<u64>,
|
seed_rotation_interval_option: Option<u64>,
|
||||||
active_window_length_option: Option<u64>,
|
active_window_length_option: Option<u64>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
LeaderSchedulerConfig {
|
LeaderSchedulerConfig {
|
||||||
bootstrap_leader,
|
|
||||||
bootstrap_height_option,
|
bootstrap_height_option,
|
||||||
leader_rotation_interval_option,
|
leader_rotation_interval_option,
|
||||||
seed_rotation_interval_option,
|
seed_rotation_interval_option,
|
||||||
|
@ -98,12 +93,12 @@ pub struct LeaderScheduler {
|
||||||
// The LeaderScheduler implements a schedule for leaders as follows:
|
// The LeaderScheduler implements a schedule for leaders as follows:
|
||||||
//
|
//
|
||||||
// 1) During the bootstrapping period of bootstrap_height PoH counts, the
|
// 1) During the bootstrapping period of bootstrap_height PoH counts, the
|
||||||
// leader is hard-coded to the input bootstrap_leader.
|
// leader is hard-coded to the bootstrap_leader that is read from the genesis block.
|
||||||
//
|
//
|
||||||
// 2) After the first seed is generated, this signals the beginning of actual leader rotation.
|
// 2) After the first seed is generated, this signals the beginning of actual leader rotation.
|
||||||
// From this point on, every seed_rotation_interval PoH counts we generate the seed based
|
// From this point on, every seed_rotation_interval PoH counts we generate the seed based
|
||||||
// on the PoH height, and use it to do a weighted sample from the set
|
// on the PoH height, and use it to do a weighted sample from the set
|
||||||
// of validators based on current stake weight. This gets you the first leader A for
|
// of validators based on current stake weight. This gets you the bootstrap leader A for
|
||||||
// the next leader_rotation_interval PoH counts. On the same PoH count we generate the seed,
|
// the next leader_rotation_interval PoH counts. On the same PoH count we generate the seed,
|
||||||
// we also order the validators based on their current stake weight, and starting
|
// we also order the validators based on their current stake weight, and starting
|
||||||
// from leader A, we then pick the next leader sequentially every leader_rotation_interval
|
// from leader A, we then pick the next leader sequentially every leader_rotation_interval
|
||||||
|
@ -114,9 +109,10 @@ pub struct LeaderScheduler {
|
||||||
// calculate the leader schedule for the upcoming seed_rotation_interval PoH counts.
|
// calculate the leader schedule for the upcoming seed_rotation_interval PoH counts.
|
||||||
impl LeaderScheduler {
|
impl LeaderScheduler {
|
||||||
pub fn from_bootstrap_leader(bootstrap_leader: Pubkey) -> Self {
|
pub fn from_bootstrap_leader(bootstrap_leader: Pubkey) -> Self {
|
||||||
let config = LeaderSchedulerConfig::new(bootstrap_leader, None, None, None, None);
|
let config = LeaderSchedulerConfig::new(None, None, None, None);
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&config);
|
let mut leader_scheduler = LeaderScheduler::new(&config);
|
||||||
leader_scheduler.use_only_bootstrap_leader = true;
|
leader_scheduler.use_only_bootstrap_leader = true;
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader;
|
||||||
leader_scheduler
|
leader_scheduler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +148,7 @@ impl LeaderScheduler {
|
||||||
seed_rotation_interval,
|
seed_rotation_interval,
|
||||||
leader_schedule: Vec::new(),
|
leader_schedule: Vec::new(),
|
||||||
last_seed_height: None,
|
last_seed_height: None,
|
||||||
bootstrap_leader: config.bootstrap_leader,
|
bootstrap_leader: Pubkey::default(),
|
||||||
bootstrap_height,
|
bootstrap_height,
|
||||||
active_window_length,
|
active_window_length,
|
||||||
seed: 0,
|
seed: 0,
|
||||||
|
@ -440,7 +436,7 @@ impl LeaderScheduler {
|
||||||
impl Default for LeaderScheduler {
|
impl Default for LeaderScheduler {
|
||||||
// Create a dummy leader scheduler
|
// Create a dummy leader scheduler
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let id = Keypair::new().pubkey();
|
let id = Pubkey::default();
|
||||||
Self::from_bootstrap_leader(id)
|
Self::from_bootstrap_leader(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -568,7 +564,6 @@ mod tests {
|
||||||
// Set up the LeaderScheduler struct
|
// Set up the LeaderScheduler struct
|
||||||
let bootstrap_leader_id = Keypair::new().pubkey();
|
let bootstrap_leader_id = Keypair::new().pubkey();
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -576,6 +571,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -663,7 +659,7 @@ mod tests {
|
||||||
|
|
||||||
// Note: The "validators" vector is already sorted by stake, so the expected order
|
// Note: The "validators" vector is already sorted by stake, so the expected order
|
||||||
// for the leader schedule can be derived by just iterating through the vector
|
// for the leader schedule can be derived by just iterating through the vector
|
||||||
// in order. The only excpetion is for the first leader in the schedule, we need to
|
// in order. The only excpetion is for the bootstrap leader in the schedule, we need to
|
||||||
// find the index into the "validators" vector where the schedule begins.
|
// find the index into the "validators" vector where the schedule begins.
|
||||||
if None == start_leader_index {
|
if None == start_leader_index {
|
||||||
start_leader_index = Some(
|
start_leader_index = Some(
|
||||||
|
@ -689,18 +685,14 @@ 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(10000);
|
let mint = Mint::new_with_leader(10000, leader_id, 500);
|
||||||
let bank = Bank::new(&mint);
|
let bank = Bank::new(&mint);
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config =
|
||||||
leader_id,
|
LeaderSchedulerConfig::new(Some(100), Some(100), Some(100), Some(active_window_length));
|
||||||
Some(100),
|
|
||||||
Some(100),
|
|
||||||
Some(100),
|
|
||||||
Some(active_window_length),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = leader_id;
|
||||||
|
|
||||||
// Insert a bunch of votes at height "start_height"
|
// Insert a bunch of votes at height "start_height"
|
||||||
let start_height = 3;
|
let start_height = 3;
|
||||||
|
@ -980,7 +972,6 @@ mod tests {
|
||||||
let active_window_length = seed_rotation_interval;
|
let active_window_length = seed_rotation_interval;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -988,6 +979,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
// Create the bank and validators
|
// Create the bank and validators
|
||||||
let mint = Mint::new(
|
let mint = Mint::new(
|
||||||
|
@ -1051,22 +1043,14 @@ 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(10000);
|
let mint = Mint::new_with_leader(10000, leader_id, 500);
|
||||||
let bank = Bank::new(&mint);
|
let bank = Bank::new(&mint);
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config =
|
||||||
leader_id,
|
LeaderSchedulerConfig::new(Some(100), Some(100), Some(100), Some(active_window_length));
|
||||||
Some(100),
|
|
||||||
Some(100),
|
|
||||||
Some(100),
|
|
||||||
Some(active_window_length),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = leader_id;
|
||||||
// Give the node some tokens
|
|
||||||
bank.transfer(5, &mint.keypair(), leader_id, bank.last_id())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Check that a node that votes twice in a row will get included in the active
|
// Check that a node that votes twice in a row will get included in the active
|
||||||
// window
|
// window
|
||||||
|
@ -1110,7 +1094,6 @@ mod tests {
|
||||||
let active_window_length = 1;
|
let active_window_length = 1;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -1118,6 +1101,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
// Check that the generate_schedule() function is being called by the
|
// Check that the generate_schedule() function is being called by the
|
||||||
// update_height() function at the correct entry heights.
|
// update_height() function at the correct entry heights.
|
||||||
|
@ -1140,11 +1124,12 @@ mod tests {
|
||||||
let bootstrap_leader_id = Keypair::new().pubkey();
|
let bootstrap_leader_id = Keypair::new().pubkey();
|
||||||
|
|
||||||
// Check defaults for LeaderScheduler
|
// Check defaults for LeaderScheduler
|
||||||
let leader_scheduler_config =
|
let leader_scheduler_config = LeaderSchedulerConfig::new(None, None, None, None);
|
||||||
LeaderSchedulerConfig::new(bootstrap_leader_id, None, None, None, None);
|
|
||||||
|
|
||||||
let leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
|
||||||
|
assert_eq!(leader_scheduler.bootstrap_leader, Pubkey::default());
|
||||||
|
|
||||||
assert_eq!(leader_scheduler.bootstrap_height, DEFAULT_BOOTSTRAP_HEIGHT);
|
assert_eq!(leader_scheduler.bootstrap_height, DEFAULT_BOOTSTRAP_HEIGHT);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -1163,14 +1148,14 @@ mod tests {
|
||||||
let active_window_length = 1;
|
let active_window_length = 1;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
Some(active_window_length),
|
Some(active_window_length),
|
||||||
);
|
);
|
||||||
|
|
||||||
let leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
assert_eq!(leader_scheduler.bootstrap_height, bootstrap_height);
|
assert_eq!(leader_scheduler.bootstrap_height, bootstrap_height);
|
||||||
|
|
||||||
|
@ -1193,7 +1178,6 @@ mod tests {
|
||||||
let active_window_length = bootstrap_height + seed_rotation_interval;
|
let active_window_length = bootstrap_height + seed_rotation_interval;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -1201,9 +1185,10 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
// Create mint and bank
|
// Create mint and bank
|
||||||
let mint = Mint::new(10000);
|
let mint = Mint::new_with_leader(10000, bootstrap_leader_id, 0);
|
||||||
let bank = Bank::new(&mint);
|
let bank = Bank::new(&mint);
|
||||||
let last_id = mint
|
let last_id = mint
|
||||||
.create_entries()
|
.create_entries()
|
||||||
|
@ -1301,7 +1286,6 @@ mod tests {
|
||||||
let active_window_length = bootstrap_height + seed_rotation_interval;
|
let active_window_length = bootstrap_height + seed_rotation_interval;
|
||||||
|
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -1309,9 +1293,10 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
let mut leader_scheduler = LeaderScheduler::new(&leader_scheduler_config);
|
||||||
|
leader_scheduler.bootstrap_leader = bootstrap_leader_id;
|
||||||
|
|
||||||
// Create mint and bank
|
// Create mint and bank
|
||||||
let mint = Mint::new(10000);
|
let mint = Mint::new_with_leader(10000, bootstrap_leader_id, 500);
|
||||||
let bank = Bank::new(&mint);
|
let bank = Bank::new(&mint);
|
||||||
let last_id = mint
|
let last_id = mint
|
||||||
.create_entries()
|
.create_entries()
|
||||||
|
|
|
@ -625,8 +625,13 @@ pub fn create_tmp_ledger_with_mint(name: &str, mint: &Mint) -> String {
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_tmp_genesis(name: &str, num: i64) -> (Mint, String) {
|
pub fn create_tmp_genesis(
|
||||||
let mint = Mint::new(num);
|
name: &str,
|
||||||
|
num: i64,
|
||||||
|
bootstrap_leader_id: Pubkey,
|
||||||
|
bootstrap_leader_tokens: i64,
|
||||||
|
) -> (Mint, String) {
|
||||||
|
let mint = Mint::new_with_leader(num, bootstrap_leader_id, bootstrap_leader_tokens);
|
||||||
let path = create_tmp_ledger_with_mint(name, &mint);
|
let path = create_tmp_ledger_with_mint(name, &mint);
|
||||||
|
|
||||||
(mint, path)
|
(mint, path)
|
||||||
|
@ -647,8 +652,10 @@ pub fn create_tmp_sample_ledger(
|
||||||
name: &str,
|
name: &str,
|
||||||
num_tokens: i64,
|
num_tokens: i64,
|
||||||
num_ending_ticks: usize,
|
num_ending_ticks: usize,
|
||||||
|
bootstrap_leader_id: Pubkey,
|
||||||
|
bootstrap_leader_tokens: i64,
|
||||||
) -> (Mint, String, Vec<Entry>) {
|
) -> (Mint, String, Vec<Entry>) {
|
||||||
let mint = Mint::new(num_tokens);
|
let mint = Mint::new_with_leader(num_tokens, bootstrap_leader_id, bootstrap_leader_tokens);
|
||||||
let path = get_tmp_ledger_path(name);
|
let path = get_tmp_ledger_path(name);
|
||||||
|
|
||||||
// Create the entries
|
// Create the entries
|
||||||
|
|
87
src/mint.rs
87
src/mint.rs
|
@ -14,10 +14,17 @@ pub struct Mint {
|
||||||
pub pkcs8: Vec<u8>,
|
pub pkcs8: Vec<u8>,
|
||||||
pubkey: Pubkey,
|
pubkey: Pubkey,
|
||||||
pub tokens: i64,
|
pub tokens: i64,
|
||||||
|
pub bootstrap_leader_id: Pubkey,
|
||||||
|
pub bootstrap_leader_tokens: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mint {
|
impl Mint {
|
||||||
pub fn new_with_pkcs8(tokens: i64, pkcs8: Vec<u8>) -> Self {
|
pub fn new_with_pkcs8(
|
||||||
|
tokens: i64,
|
||||||
|
pkcs8: Vec<u8>,
|
||||||
|
bootstrap_leader_id: Pubkey,
|
||||||
|
bootstrap_leader_tokens: i64,
|
||||||
|
) -> Self {
|
||||||
let keypair =
|
let keypair =
|
||||||
Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new");
|
Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new");
|
||||||
let pubkey = keypair.pubkey();
|
let pubkey = keypair.pubkey();
|
||||||
|
@ -25,15 +32,29 @@ impl Mint {
|
||||||
pkcs8,
|
pkcs8,
|
||||||
pubkey,
|
pubkey,
|
||||||
tokens,
|
tokens,
|
||||||
|
bootstrap_leader_id,
|
||||||
|
bootstrap_leader_tokens,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_leader(
|
||||||
|
tokens: i64,
|
||||||
|
bootstrap_leader: Pubkey,
|
||||||
|
bootstrap_leader_tokens: i64,
|
||||||
|
) -> Self {
|
||||||
|
let rnd = SystemRandom::new();
|
||||||
|
let pkcs8 = Keypair::generate_pkcs8(&rnd)
|
||||||
|
.expect("generate_pkcs8 in mint pub fn new")
|
||||||
|
.to_vec();
|
||||||
|
Self::new_with_pkcs8(tokens, pkcs8, bootstrap_leader, bootstrap_leader_tokens)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(tokens: i64) -> Self {
|
pub fn new(tokens: i64) -> Self {
|
||||||
let rnd = SystemRandom::new();
|
let rnd = SystemRandom::new();
|
||||||
let pkcs8 = Keypair::generate_pkcs8(&rnd)
|
let pkcs8 = Keypair::generate_pkcs8(&rnd)
|
||||||
.expect("generate_pkcs8 in mint pub fn new")
|
.expect("generate_pkcs8 in mint pub fn new")
|
||||||
.to_vec();
|
.to_vec();
|
||||||
Self::new_with_pkcs8(tokens, pkcs8)
|
Self::new_with_pkcs8(tokens, pkcs8, Pubkey::default(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seed(&self) -> Hash {
|
pub fn seed(&self) -> Hash {
|
||||||
|
@ -41,7 +62,7 @@ impl Mint {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_id(&self) -> Hash {
|
pub fn last_id(&self) -> Hash {
|
||||||
self.create_entries()[1].id
|
self.create_entries().last().unwrap().id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keypair(&self) -> Keypair {
|
pub fn keypair(&self) -> Keypair {
|
||||||
|
@ -52,15 +73,34 @@ impl Mint {
|
||||||
self.pubkey
|
self.pubkey
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_transactions(&self) -> Vec<Transaction> {
|
pub fn create_transaction(&self) -> Vec<Transaction> {
|
||||||
let keypair = self.keypair();
|
let keypair = self.keypair();
|
||||||
let tx = Transaction::system_move(&keypair, self.pubkey(), self.tokens, self.seed(), 0);
|
// Check if creating the leader genesis entries is necessary
|
||||||
vec![tx]
|
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> {
|
pub fn create_entries(&self) -> Vec<Entry> {
|
||||||
let e0 = Entry::new(&self.seed(), 0, vec![]);
|
let e0 = Entry::new(&self.seed(), 0, vec![]);
|
||||||
let e1 = Entry::new(&e0.id, 1, self.create_transactions());
|
|
||||||
|
// Create the transactions that give the mint the initial tokens, and gives the first
|
||||||
|
// leader the initial tokens
|
||||||
|
let e1 = Entry::new(&self.seed(), 0, self.create_transaction());
|
||||||
vec![e0, e1]
|
vec![e0, e1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +114,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_create_transactions() {
|
fn test_create_transactions() {
|
||||||
let mut transactions = Mint::new(100).create_transactions().into_iter();
|
let mut transactions = Mint::new(100).create_transaction().into_iter();
|
||||||
let tx = transactions.next().unwrap();
|
let tx = transactions.next().unwrap();
|
||||||
assert_eq!(tx.instructions.len(), 1);
|
assert_eq!(tx.instructions.len(), 1);
|
||||||
assert!(SystemProgram::check_id(tx.program_id(0)));
|
assert!(SystemProgram::check_id(tx.program_id(0)));
|
||||||
|
@ -85,9 +125,40 @@ mod tests {
|
||||||
assert_eq!(transactions.next(), None);
|
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!(SystemProgram::check_id(tx.program_id(0)));
|
||||||
|
assert!(SystemProgram::check_id(tx.program_id(1)));
|
||||||
|
let instruction: SystemProgram = deserialize(tx.userdata(0)).unwrap();
|
||||||
|
if let SystemProgram::Move { tokens } = instruction {
|
||||||
|
assert_eq!(tokens, 100);
|
||||||
|
}
|
||||||
|
let instruction: SystemProgram = deserialize(tx.userdata(1)).unwrap();
|
||||||
|
if let SystemProgram::Move { tokens } = instruction {
|
||||||
|
assert_eq!(tokens, 1);
|
||||||
|
}
|
||||||
|
assert_eq!(transactions.next(), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_verify_entries() {
|
fn test_verify_entries() {
|
||||||
let entries = Mint::new(100).create_entries();
|
let entries = Mint::new(100).create_entries();
|
||||||
assert!(entries[..].verify(&entries[0].id));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,9 +125,11 @@ pub fn bind_in_range(range: (u16, u16)) -> io::Result<(u16, UdpSocket)> {
|
||||||
let sock = sock.into_udp_socket();
|
let sock = sock.into_udp_socket();
|
||||||
break Result::Ok((sock.local_addr().unwrap().port(), sock));
|
break Result::Ok((sock.local_addr().unwrap().port(), sock));
|
||||||
}
|
}
|
||||||
Err(err) => if err.kind() != io::ErrorKind::AddrInUse || tries_left == 0 {
|
Err(err) => {
|
||||||
return Err(err);
|
if err.kind() != io::ErrorKind::AddrInUse || tries_left == 0 {
|
||||||
},
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tries_left -= 1;
|
tries_left -= 1;
|
||||||
}
|
}
|
||||||
|
@ -171,9 +173,11 @@ pub fn find_available_port_in_range(range: (u16, u16)) -> io::Result<u16> {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
break Ok(rand_port);
|
break Ok(rand_port);
|
||||||
}
|
}
|
||||||
Err(err) => if err.kind() != io::ErrorKind::AddrInUse || tries_left == 0 {
|
Err(err) => {
|
||||||
return Err(err);
|
if err.kind() != io::ErrorKind::AddrInUse || tries_left == 0 {
|
||||||
},
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tries_left -= 1;
|
tries_left -= 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,9 +378,11 @@ impl Blob {
|
||||||
}
|
}
|
||||||
return Err(Error::IO(e));
|
return Err(Error::IO(e));
|
||||||
}
|
}
|
||||||
Ok(()) => if i == 0 {
|
Ok(()) => {
|
||||||
socket.set_nonblocking(true)?;
|
if i == 0 {
|
||||||
},
|
socket.set_nonblocking(true)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
v.push(r);
|
v.push(r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,12 +255,17 @@ 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_me = ClusterInfo::new(my_node.info.clone()).expect("ClusterInfo::new");
|
let cluster_info_me = ClusterInfo::new(my_node.info.clone()).expect("ClusterInfo::new");
|
||||||
|
|
||||||
|
// Create keypair for the old leader
|
||||||
|
let old_leader_id = Keypair::new().pubkey();
|
||||||
|
|
||||||
// Create a ledger
|
// Create a ledger
|
||||||
let num_ending_ticks = 1;
|
let num_ending_ticks = 1;
|
||||||
let (mint, my_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
let (mint, my_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
||||||
"test_replicate_stage_leader_rotation_exit",
|
"test_replicate_stage_leader_rotation_exit",
|
||||||
10_000,
|
10_000,
|
||||||
num_ending_ticks,
|
num_ending_ticks,
|
||||||
|
old_leader_id,
|
||||||
|
500,
|
||||||
);
|
);
|
||||||
let mut last_id = genesis_entries
|
let mut last_id = genesis_entries
|
||||||
.last()
|
.last()
|
||||||
|
@ -285,12 +290,10 @@ mod test {
|
||||||
|
|
||||||
// Set up the LeaderScheduler so that this this node becomes the leader at
|
// Set up the LeaderScheduler so that this this node becomes the leader at
|
||||||
// bootstrap_height = num_bootstrap_slots * leader_rotation_interval
|
// bootstrap_height = num_bootstrap_slots * leader_rotation_interval
|
||||||
let old_leader_id = Keypair::new().pubkey();
|
|
||||||
let leader_rotation_interval = 10;
|
let leader_rotation_interval = 10;
|
||||||
let num_bootstrap_slots = 2;
|
let num_bootstrap_slots = 2;
|
||||||
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
old_leader_id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(leader_rotation_interval * 2),
|
Some(leader_rotation_interval * 2),
|
||||||
|
|
|
@ -195,15 +195,17 @@ mod tests {
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
let done = Arc::new(AtomicBool::new(false));
|
let done = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
let leader_ledger_path = "replicator_test_leader_ledger";
|
|
||||||
let (mint, leader_ledger_path) = create_tmp_genesis(leader_ledger_path, 100);
|
|
||||||
|
|
||||||
info!("starting leader node");
|
info!("starting leader node");
|
||||||
let leader_keypair = Arc::new(Keypair::new());
|
let leader_keypair = Arc::new(Keypair::new());
|
||||||
let leader_node = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
|
let leader_node = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
|
||||||
let network_addr = leader_node.sockets.gossip.local_addr().unwrap();
|
let network_addr = leader_node.sockets.gossip.local_addr().unwrap();
|
||||||
let leader_info = leader_node.info.clone();
|
let leader_info = leader_node.info.clone();
|
||||||
let vote_account_keypair = Arc::new(Keypair::new());
|
let vote_account_keypair = Arc::new(Keypair::new());
|
||||||
|
|
||||||
|
let leader_ledger_path = "replicator_test_leader_ledger";
|
||||||
|
let (mint, leader_ledger_path) =
|
||||||
|
create_tmp_genesis(leader_ledger_path, 100, leader_info.id, 1);
|
||||||
|
|
||||||
let leader = Fullnode::new(
|
let leader = Fullnode::new(
|
||||||
leader_node,
|
leader_node,
|
||||||
&leader_ledger_path,
|
&leader_ledger_path,
|
||||||
|
|
|
@ -305,8 +305,13 @@ 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) =
|
let (_mint, ledger_path, _genesis) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("storage_stage_process_entries", 1000, 1);
|
"storage_stage_process_entries",
|
||||||
|
1000,
|
||||||
|
1,
|
||||||
|
Keypair::new().pubkey(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
let entries = make_tiny_test_entries(128);
|
let entries = make_tiny_test_entries(128);
|
||||||
{
|
{
|
||||||
|
@ -363,8 +368,13 @@ 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) =
|
let (_mint, ledger_path, _genesis) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("storage_stage_process_entries", 1000, 1);
|
"storage_stage_process_entries",
|
||||||
|
1000,
|
||||||
|
1,
|
||||||
|
Keypair::new().pubkey(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
|
||||||
let entries = make_tiny_test_entries(128);
|
let entries = make_tiny_test_entries(128);
|
||||||
{
|
{
|
||||||
|
|
|
@ -1074,15 +1074,15 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_wallet_process_command() {
|
fn test_wallet_process_command() {
|
||||||
let (alice, ledger_path) = create_tmp_genesis("wallet_process_command", 10_000_000);
|
|
||||||
let mut bank = Bank::new(&alice);
|
|
||||||
|
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
|
|
||||||
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 leader_data = leader.info.clone();
|
let leader_data = leader.info.clone();
|
||||||
let leader_data1 = leader.info.clone();
|
let leader_data1 = leader.info.clone();
|
||||||
|
let (alice, ledger_path) =
|
||||||
|
create_tmp_genesis("wallet_process_command", 10_000_000, leader_data.id, 1000);
|
||||||
|
let mut bank = Bank::new(&alice);
|
||||||
|
|
||||||
let mut config = WalletConfig::default();
|
let mut config = WalletConfig::default();
|
||||||
let rpc_port = 12345; // Needs to be distinct known number to not conflict with other tests
|
let rpc_port = 12345; // Needs to be distinct known number to not conflict with other tests
|
||||||
|
@ -1158,13 +1158,14 @@ mod tests {
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_wallet_request_airdrop() {
|
fn test_wallet_request_airdrop() {
|
||||||
let (alice, ledger_path) = create_tmp_genesis("wallet_request_airdrop", 10_000_000);
|
|
||||||
let mut bank = Bank::new(&alice);
|
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
|
|
||||||
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 leader_data = leader.info.clone();
|
let leader_data = leader.info.clone();
|
||||||
|
let (alice, ledger_path) =
|
||||||
|
create_tmp_genesis("wallet_request_airdrop", 10_000_000, leader_data.id, 1000);
|
||||||
|
let mut bank = Bank::new(&alice);
|
||||||
|
|
||||||
let rpc_port = 11111; // Needs to be distinct known number to not conflict with other tests
|
let rpc_port = 11111; // Needs to be distinct known number to not conflict with other tests
|
||||||
|
|
||||||
|
@ -1237,9 +1238,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_wallet_timestamp_tx() {
|
fn test_wallet_timestamp_tx() {
|
||||||
let (alice, ledger_path) = create_tmp_genesis("wallet_timestamp_tx", 10_000_000);
|
|
||||||
let mut bank = Bank::new(&alice);
|
|
||||||
|
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
|
|
||||||
let leader_keypair = Arc::new(Keypair::new());
|
let leader_keypair = Arc::new(Keypair::new());
|
||||||
|
@ -1247,6 +1245,9 @@ mod tests {
|
||||||
let leader_data = leader.info.clone();
|
let leader_data = leader.info.clone();
|
||||||
let leader_data1 = leader.info.clone();
|
let leader_data1 = leader.info.clone();
|
||||||
let leader_data2 = leader.info.clone();
|
let leader_data2 = leader.info.clone();
|
||||||
|
let (alice, ledger_path) =
|
||||||
|
create_tmp_genesis("wallet_timestamp_tx", 10_000_000, leader_data.id, 1000);
|
||||||
|
let mut bank = Bank::new(&alice);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
|
@ -1364,14 +1365,15 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_wallet_witness_tx() {
|
fn test_wallet_witness_tx() {
|
||||||
let (alice, ledger_path) = create_tmp_genesis("wallet_witness_tx", 10_000_000);
|
|
||||||
let mut bank = Bank::new(&alice);
|
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
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 leader_data = leader.info.clone();
|
let leader_data = leader.info.clone();
|
||||||
let leader_data1 = leader.info.clone();
|
let leader_data1 = leader.info.clone();
|
||||||
let leader_data2 = leader.info.clone();
|
let leader_data2 = leader.info.clone();
|
||||||
|
let (alice, ledger_path) =
|
||||||
|
create_tmp_genesis("wallet_witness_tx", 10_000_000, leader_data.id, 1000);
|
||||||
|
let mut bank = Bank::new(&alice);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
|
@ -1486,8 +1488,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_wallet_cancel_tx() {
|
fn test_wallet_cancel_tx() {
|
||||||
let (alice, ledger_path) = create_tmp_genesis("wallet_cancel_tx", 10_000_000);
|
|
||||||
let mut bank = Bank::new(&alice);
|
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
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());
|
||||||
|
@ -1495,6 +1495,10 @@ mod tests {
|
||||||
let leader_data1 = leader.info.clone();
|
let leader_data1 = leader.info.clone();
|
||||||
let leader_data2 = leader.info.clone();
|
let leader_data2 = leader.info.clone();
|
||||||
|
|
||||||
|
let (alice, ledger_path) =
|
||||||
|
create_tmp_genesis("wallet_cancel_tx", 10_000_000, leader_data.id, 1000);
|
||||||
|
let mut bank = Bank::new(&alice);
|
||||||
|
|
||||||
let mut config_payer = WalletConfig::default();
|
let mut config_payer = WalletConfig::default();
|
||||||
let mut config_witness = WalletConfig::default();
|
let mut config_witness = WalletConfig::default();
|
||||||
let rpc_port = 13456; // Needs to be distinct known number to not conflict with other tests
|
let rpc_port = 13456; // Needs to be distinct known number to not conflict with other tests
|
||||||
|
|
|
@ -116,7 +116,8 @@ 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) = create_tmp_genesis("multi_node_ledger_window", 10_000);
|
let (alice, leader_ledger_path) =
|
||||||
|
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());
|
||||||
|
|
||||||
// make a copy at zero
|
// make a copy at zero
|
||||||
|
@ -142,11 +143,6 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
|
||||||
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send leader some tokens to vote
|
|
||||||
let leader_balance =
|
|
||||||
send_tx_and_retry_get_balance(&leader_data, &alice, &leader_pubkey, 500, None).unwrap();
|
|
||||||
info!("leader balance {}", leader_balance);
|
|
||||||
|
|
||||||
// start up another validator from zero, converge and then check
|
// start up another validator from zero, converge and then check
|
||||||
// balances
|
// balances
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
|
@ -166,7 +162,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
|
||||||
// Send validator some tokens to vote
|
// Send validator some tokens to vote
|
||||||
let validator_balance =
|
let validator_balance =
|
||||||
send_tx_and_retry_get_balance(&leader_data, &alice, &validator_pubkey, 500, None).unwrap();
|
send_tx_and_retry_get_balance(&leader_data, &alice, &validator_pubkey, 500, None).unwrap();
|
||||||
info!("leader balance {}", validator_balance);
|
info!("validator balance {}", validator_balance);
|
||||||
|
|
||||||
// contains the leader and new node
|
// contains the leader and new node
|
||||||
info!("converging....");
|
info!("converging....");
|
||||||
|
@ -215,8 +211,12 @@ 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, leader_ledger_path) =
|
let (alice, leader_ledger_path) = create_tmp_genesis(
|
||||||
create_tmp_genesis("multi_node_validator_catchup_from_zero", 10_000);
|
"multi_node_validator_catchup_from_zero",
|
||||||
|
10_000,
|
||||||
|
leader_data.id,
|
||||||
|
500,
|
||||||
|
);
|
||||||
ledger_paths.push(leader_ledger_path.clone());
|
ledger_paths.push(leader_ledger_path.clone());
|
||||||
|
|
||||||
let zero_ledger_path = tmp_copy_ledger(
|
let zero_ledger_path = tmp_copy_ledger(
|
||||||
|
@ -235,11 +235,6 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
|
||||||
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send leader some tokens to vote
|
|
||||||
let leader_balance =
|
|
||||||
send_tx_and_retry_get_balance(&leader_data, &alice, &leader_pubkey, 500, None).unwrap();
|
|
||||||
info!("leader balance {}", leader_balance);
|
|
||||||
|
|
||||||
let mut nodes = vec![server];
|
let mut nodes = vec![server];
|
||||||
for _ in 0..N {
|
for _ in 0..N {
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
|
@ -359,7 +354,8 @@ 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, leader_ledger_path) = create_tmp_genesis("multi_node_basic", 10_000);
|
let (alice, leader_ledger_path) =
|
||||||
|
create_tmp_genesis("multi_node_basic", 10_000, leader_data.id, 500);
|
||||||
ledger_paths.push(leader_ledger_path.clone());
|
ledger_paths.push(leader_ledger_path.clone());
|
||||||
let server = Fullnode::new(
|
let server = Fullnode::new(
|
||||||
leader,
|
leader,
|
||||||
|
@ -371,11 +367,6 @@ fn test_multi_node_basic() {
|
||||||
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send leader some tokens to vote
|
|
||||||
let leader_balance =
|
|
||||||
send_tx_and_retry_get_balance(&leader_data, &alice, &leader_pubkey, 500, None).unwrap();
|
|
||||||
info!("leader balance {}", leader_balance);
|
|
||||||
|
|
||||||
let mut nodes = vec![server];
|
let mut nodes = vec![server];
|
||||||
for _ in 0..N {
|
for _ in 0..N {
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
|
@ -437,7 +428,8 @@ fn test_boot_validator_from_file() -> result::Result<()> {
|
||||||
let leader_pubkey = leader_keypair.pubkey();
|
let leader_pubkey = leader_keypair.pubkey();
|
||||||
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, leader_ledger_path) = create_tmp_genesis("boot_validator_from_file", 100_000);
|
let (alice, leader_ledger_path) =
|
||||||
|
create_tmp_genesis("boot_validator_from_file", 100_000, leader_pubkey, 1000);
|
||||||
let mut ledger_paths = Vec::new();
|
let mut ledger_paths = Vec::new();
|
||||||
ledger_paths.push(leader_ledger_path.clone());
|
ledger_paths.push(leader_ledger_path.clone());
|
||||||
|
|
||||||
|
@ -485,8 +477,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_leader(ledger_path: &str) -> (NodeInfo, Fullnode) {
|
fn create_leader(ledger_path: &str, leader_keypair: Arc<Keypair>) -> (NodeInfo, Fullnode) {
|
||||||
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 leader_data = leader.info.clone();
|
let leader_data = leader.info.clone();
|
||||||
let leader_fullnode = Fullnode::new(
|
let leader_fullnode = Fullnode::new(
|
||||||
|
@ -509,13 +500,17 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
|
||||||
// ledger (currently up to WINDOW_SIZE entries)
|
// ledger (currently up to WINDOW_SIZE entries)
|
||||||
logger::setup();
|
logger::setup();
|
||||||
|
|
||||||
|
let leader_keypair = Arc::new(Keypair::new());
|
||||||
|
let initial_leader_balance = 500;
|
||||||
let (alice, ledger_path) = create_tmp_genesis(
|
let (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 i64,
|
100_000 + 500 * solana::window_service::MAX_REPAIR_BACKOFF as i64,
|
||||||
|
leader_keypair.pubkey(),
|
||||||
|
initial_leader_balance,
|
||||||
);
|
);
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
|
|
||||||
let (leader_data, leader_fullnode) = create_leader(&ledger_path);
|
let (leader_data, leader_fullnode) = create_leader(&ledger_path, leader_keypair.clone());
|
||||||
|
|
||||||
// lengthen the ledger
|
// lengthen the ledger
|
||||||
let leader_balance =
|
let leader_balance =
|
||||||
|
@ -530,7 +525,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
|
||||||
|
|
||||||
// restart the leader
|
// restart the leader
|
||||||
leader_fullnode.close()?;
|
leader_fullnode.close()?;
|
||||||
let (leader_data, leader_fullnode) = create_leader(&ledger_path);
|
let (leader_data, leader_fullnode) = create_leader(&ledger_path, leader_keypair.clone());
|
||||||
|
|
||||||
// lengthen the ledger
|
// lengthen the ledger
|
||||||
let leader_balance =
|
let leader_balance =
|
||||||
|
@ -539,7 +534,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
|
||||||
|
|
||||||
// restart the leader
|
// restart the leader
|
||||||
leader_fullnode.close()?;
|
leader_fullnode.close()?;
|
||||||
let (leader_data, leader_fullnode) = create_leader(&ledger_path);
|
let (leader_data, leader_fullnode) = create_leader(&ledger_path, leader_keypair);
|
||||||
|
|
||||||
// start validator from old ledger
|
// start validator from old ledger
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
|
@ -603,7 +598,8 @@ 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, leader_ledger_path) = create_tmp_genesis("multi_node_dynamic_network", 10_000_000);
|
let (alice, leader_ledger_path) =
|
||||||
|
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();
|
||||||
ledger_paths.push(leader_ledger_path.clone());
|
ledger_paths.push(leader_ledger_path.clone());
|
||||||
|
@ -621,16 +617,6 @@ fn test_multi_node_dynamic_network() {
|
||||||
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
LeaderScheduler::from_bootstrap_leader(leader_pubkey),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send leader some tokens to vote
|
|
||||||
let leader_balance = send_tx_and_retry_get_balance(
|
|
||||||
&leader_data,
|
|
||||||
&alice_arc.read().unwrap(),
|
|
||||||
&leader_pubkey,
|
|
||||||
500,
|
|
||||||
None,
|
|
||||||
).unwrap();
|
|
||||||
info!("leader balance {}", leader_balance);
|
|
||||||
|
|
||||||
info!("{} LEADER", leader_data.id);
|
info!("{} LEADER", leader_data.id);
|
||||||
let leader_balance = retry_send_tx_and_retry_get_balance(
|
let leader_balance = retry_send_tx_and_retry_get_balance(
|
||||||
&leader_data,
|
&leader_data,
|
||||||
|
@ -804,6 +790,8 @@ fn test_leader_to_validator_transition() {
|
||||||
"test_leader_to_validator_transition",
|
"test_leader_to_validator_transition",
|
||||||
10_000,
|
10_000,
|
||||||
num_ending_ticks,
|
num_ending_ticks,
|
||||||
|
leader_info.id,
|
||||||
|
500,
|
||||||
);
|
);
|
||||||
|
|
||||||
let last_id = genesis_entries
|
let last_id = genesis_entries
|
||||||
|
@ -821,7 +809,6 @@ fn test_leader_to_validator_transition() {
|
||||||
// Start the leader node
|
// Start the leader node
|
||||||
let bootstrap_height = leader_rotation_interval;
|
let bootstrap_height = leader_rotation_interval;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
leader_info.id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(leader_rotation_interval * 2),
|
Some(leader_rotation_interval * 2),
|
||||||
|
@ -929,8 +916,13 @@ 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) =
|
let (mint, leader_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("test_leader_validator_basic", 10_000, num_ending_ticks);
|
"test_leader_validator_basic",
|
||||||
|
10_000,
|
||||||
|
num_ending_ticks,
|
||||||
|
leader_info.id,
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
|
||||||
let validator_ledger_path = tmp_copy_ledger(&leader_ledger_path, "test_leader_validator_basic");
|
let validator_ledger_path = tmp_copy_ledger(&leader_ledger_path, "test_leader_validator_basic");
|
||||||
|
|
||||||
|
@ -955,7 +947,6 @@ fn test_leader_validator_basic() {
|
||||||
let num_bootstrap_slots = 2;
|
let num_bootstrap_slots = 2;
|
||||||
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
leader_info.id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(leader_rotation_interval * 2),
|
Some(leader_rotation_interval * 2),
|
||||||
|
@ -1095,8 +1086,13 @@ 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, bootstrap_leader_ledger_path, genesis_entries) =
|
let (mint, bootstrap_leader_ledger_path, genesis_entries) = create_tmp_sample_ledger(
|
||||||
create_tmp_sample_ledger("test_dropped_handoff_recovery", 10_000, num_ending_ticks);
|
"test_dropped_handoff_recovery",
|
||||||
|
10_000,
|
||||||
|
num_ending_ticks,
|
||||||
|
bootstrap_leader_info.id,
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
|
||||||
let last_id = genesis_entries
|
let last_id = genesis_entries
|
||||||
.last()
|
.last()
|
||||||
|
@ -1137,7 +1133,6 @@ fn test_dropped_handoff_recovery() {
|
||||||
let seed_rotation_interval = num_slots_per_epoch * leader_rotation_interval;
|
let seed_rotation_interval = num_slots_per_epoch * leader_rotation_interval;
|
||||||
let bootstrap_height = initial_tick_height + 1;
|
let bootstrap_height = initial_tick_height + 1;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_info.id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
@ -1248,6 +1243,8 @@ fn test_full_leader_validator_network() {
|
||||||
"test_full_leader_validator_network",
|
"test_full_leader_validator_network",
|
||||||
10_000,
|
10_000,
|
||||||
num_ending_ticks,
|
num_ending_ticks,
|
||||||
|
bootstrap_leader_info.id,
|
||||||
|
500,
|
||||||
);
|
);
|
||||||
|
|
||||||
let last_tick_id = genesis_entries
|
let last_tick_id = genesis_entries
|
||||||
|
@ -1298,7 +1295,6 @@ fn test_full_leader_validator_network() {
|
||||||
let seed_rotation_interval = num_slots_per_epoch * leader_rotation_interval;
|
let seed_rotation_interval = num_slots_per_epoch * leader_rotation_interval;
|
||||||
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_leader_info.id,
|
|
||||||
Some(bootstrap_height),
|
Some(bootstrap_height),
|
||||||
Some(leader_rotation_interval),
|
Some(leader_rotation_interval),
|
||||||
Some(seed_rotation_interval),
|
Some(seed_rotation_interval),
|
||||||
|
|
Loading…
Reference in New Issue