Change write_entries() and create_tmp_ledger() to take ticks_per_slot (#2736)

* Change write_entries() and create_tmp_ledger() to take ticks_per_slot

* PR nits
This commit is contained in:
carllin 2019-02-12 13:14:33 -08:00 committed by GitHub
parent 8b39eb5e4e
commit be71f49d80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 433 additions and 204 deletions

View File

@ -32,8 +32,15 @@ fn bad_arguments() {
#[test]
fn nominal() {
let keypair = Arc::new(Keypair::new());
let (_mint_keypair, ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger("test_ledger_tool_nominal", 100, 9, keypair.pubkey(), 50);
let (_mint_keypair, ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"test_ledger_tool_nominal",
100,
9,
keypair.pubkey(),
50,
std::u64::MAX,
);
// Basic validation
let output = run_ledger_tool(&["-l", &ledger_path, "verify"]);

View File

@ -479,21 +479,44 @@ impl Blocktree {
self.insert_data_blobs(blobs)
}
pub fn write_entries<I>(&self, slot: u64, index: u64, entries: I) -> Result<()>
pub fn write_entries<I>(
&self,
start_slot: u64,
num_ticks_in_start_slot: u64,
ticks_per_slot: u64,
start_index: u64,
entries: I,
) -> Result<()>
where
I: IntoIterator,
I::Item: Borrow<Entry>,
{
let blobs: Vec<_> = entries
.into_iter()
.enumerate()
.map(|(idx, entry)| {
let mut b = entry.borrow().to_blob();
b.set_index(idx as u64 + index);
b.set_slot(slot);
b
})
.collect();
assert!(num_ticks_in_start_slot < ticks_per_slot);
let mut remaining_ticks_in_slot = ticks_per_slot - num_ticks_in_start_slot;
let mut blobs = vec![];
let mut current_index = start_index;
let mut current_slot = start_slot;
// Find all the entries for start_slot
for entry in entries {
if remaining_ticks_in_slot == 0 {
current_slot += 1;
current_index = 0;
remaining_ticks_in_slot = ticks_per_slot;
}
let mut b = entry.borrow().to_blob();
b.set_index(current_index);
b.set_slot(current_slot);
blobs.push(b);
current_index += 1;
if entry.borrow().is_tick() {
remaining_ticks_in_slot -= 1;
}
}
self.write_blobs(&blobs)
}
@ -1249,16 +1272,22 @@ impl Iterator for EntryIterator {
}
}
pub fn create_new_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Result<(u64, Hash)> {
// Returns a tuple (entry_height, tick_height, last_id), corresponding to the
// total number of entries, the number of ticks, and the last id generated in the
// new ledger
pub fn create_new_ledger(
ledger_path: &str,
genesis_block: &GenesisBlock,
) -> Result<(u64, u64, Hash)> {
Blocktree::destroy(ledger_path)?;
genesis_block.write(&ledger_path)?;
// Add a single tick linked back to the genesis_block to bootstrap the ledger
let blocktree = Blocktree::open(ledger_path)?;
let entries = crate::entry::create_ticks(1, genesis_block.last_id());
blocktree.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)?;
blocktree.write_entries(DEFAULT_SLOT_HEIGHT, 0, std::u64::MAX, 0, &entries)?;
Ok((1, entries[0].id))
Ok((1, 1, entries[0].id))
}
pub fn genesis<'a, I>(ledger_path: &str, entries: I) -> Result<()>
@ -1303,11 +1332,12 @@ pub fn create_tmp_sample_ledger(
num_extra_ticks: u64,
bootstrap_leader_id: Pubkey,
bootstrap_leader_tokens: u64,
) -> (Keypair, String, u64, Hash, Hash) {
ticks_per_slot: u64,
) -> (Keypair, String, u64, u64, Hash, Hash) {
let (genesis_block, mint_keypair) =
GenesisBlock::new_with_leader(num_tokens, bootstrap_leader_id, bootstrap_leader_tokens);
let ledger_path = get_tmp_ledger_path(name);
let (mut entry_height, mut last_entry_id) =
let (mut entry_height, mut tick_height, mut last_entry_id) =
create_new_ledger(&ledger_path, &genesis_block).unwrap();
let mut last_id = genesis_block.last_id();
@ -1315,8 +1345,17 @@ pub fn create_tmp_sample_ledger(
let entries = crate::entry::create_ticks(num_extra_ticks, last_entry_id);
let blocktree = Blocktree::open(&ledger_path).unwrap();
// create_new_ledger creates one beginning tick
tick_height += num_extra_ticks;
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, entry_height, &entries)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
entry_height,
&entries,
)
.unwrap();
entry_height += entries.len() as u64;
last_id = entries.last().unwrap().id;
@ -1325,6 +1364,7 @@ pub fn create_tmp_sample_ledger(
(
mint_keypair,
ledger_path,
tick_height,
entry_height,
last_id,
last_entry_id,
@ -1808,6 +1848,8 @@ mod tests {
ledger
.write_entries(
0u64,
0,
std::u64::MAX,
(entries.len() - 1) as u64,
&entries[entries.len() - 1..],
)

View File

@ -148,8 +148,9 @@ mod tests {
let out_path = Path::new("test_chacha_encrypt_file_output.txt.enc");
let entries = make_tiny_deterministic_test_entries(32);
let ticks_per_slot = 16;
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)
.write_entries(DEFAULT_SLOT_HEIGHT, 0, ticks_per_slot, 0, &entries)
.unwrap();
let mut key = hex!(

View File

@ -128,8 +128,10 @@ mod tests {
let ledger_dir = "test_encrypt_file_many_keys_single";
let ledger_path = get_tmp_ledger_path(ledger_dir);
let blocktree = Arc::new(Blocktree::open(&ledger_path).unwrap());
let ticks_per_slot = 16;
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)
.write_entries(DEFAULT_SLOT_HEIGHT, 0, ticks_per_slot, 0, &entries)
.unwrap();
let out_path = Path::new("test_chacha_encrypt_file_many_keys_single_output.txt.enc");
@ -162,8 +164,9 @@ mod tests {
let ledger_dir = "test_encrypt_file_many_keys_multiple";
let ledger_path = get_tmp_ledger_path(ledger_dir);
let blocktree = Arc::new(Blocktree::open(&ledger_path).unwrap());
let ticks_per_slot = 16;
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)
.write_entries(DEFAULT_SLOT_HEIGHT, 0, ticks_per_slot, 0, &entries)
.unwrap();
let out_path = Path::new("test_chacha_encrypt_file_many_keys_multiple_output.txt.enc");

View File

@ -521,13 +521,12 @@ impl Service for Fullnode {
mod tests {
use super::*;
use crate::blob_fetch_stage::BlobFetchStage;
use crate::blocktree::{create_tmp_sample_ledger, tmp_copy_ledger};
use crate::blocktree::{create_tmp_sample_ledger, tmp_copy_ledger, DEFAULT_SLOT_HEIGHT};
use crate::entry::make_consecutive_blobs;
use crate::entry::EntrySlice;
use crate::gossip_service::{converge, make_listening_node};
use crate::leader_scheduler::make_active_set_entries;
use crate::streamer::responder;
use std::cmp::min;
use std::fs::remove_dir_all;
use std::sync::atomic::Ordering;
use std::thread::sleep;
@ -539,8 +538,21 @@ mod tests {
let validator_keypair = Keypair::new();
let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey());
let (_mint_keypair, validator_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger("validator_exit", 10_000, 0, leader_keypair.pubkey(), 1000);
let (
_mint_keypair,
validator_ledger_path,
_tick_height,
_last_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
"validator_exit",
10_000,
0,
leader_keypair.pubkey(),
1000,
std::u64::MAX,
);
let validator = Fullnode::new(
validator_node,
@ -567,6 +579,7 @@ mod tests {
let (
_mint_keypair,
validator_ledger_path,
_tick_height,
_last_entry_height,
_last_id,
_last_entry_id,
@ -576,6 +589,7 @@ mod tests {
0,
leader_keypair.pubkey(),
1000,
std::u64::MAX,
);
ledger_paths.push(validator_ledger_path.clone());
Fullnode::new(
@ -610,20 +624,6 @@ mod tests {
let bootstrap_leader_node =
Node::new_localhost_with_pubkey(bootstrap_leader_keypair.pubkey());
let (
_mint_keypair,
bootstrap_leader_ledger_path,
_genesis_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
"test_leader_to_leader_transition",
10_000,
1,
bootstrap_leader_keypair.pubkey(),
500,
);
// Once the bootstrap leader hits the second epoch, because there are no other choices in
// the active set, this leader will remain the leader in the second epoch. In the second
// epoch, check that the same leader knows to shut down and restart as a leader again.
@ -634,6 +634,22 @@ mod tests {
let leader_scheduler_config =
LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, active_window_length);
let (
_mint_keypair,
bootstrap_leader_ledger_path,
_tick_height,
_genesis_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
"test_leader_to_leader_transition",
10_000,
1,
bootstrap_leader_keypair.pubkey(),
500,
ticks_per_slot,
);
let bootstrap_leader_keypair = Arc::new(bootstrap_leader_keypair);
let voting_keypair = VotingKeypair::new_local(&bootstrap_leader_keypair);
// Start the bootstrap leader
@ -973,20 +989,21 @@ mod tests {
num_genesis_ticks: u64,
num_ending_ticks: u64,
test_name: &str,
ticks_per_block: u64,
ticks_per_slot: u64,
) -> (Node, Node, String, u64, Hash) {
// Make a leader identity
let leader_node = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
// Create validator identity
assert!(num_genesis_ticks <= ticks_per_block);
let (mint_keypair, ledger_path, genesis_entry_height, last_id, last_entry_id) =
assert!(num_genesis_ticks <= ticks_per_slot);
let (mint_keypair, ledger_path, tick_height, mut entry_height, last_id, last_entry_id) =
create_tmp_sample_ledger(
test_name,
10_000,
num_genesis_ticks,
leader_node.info.id,
500,
ticks_per_slot,
);
let validator_node = Node::new_localhost_with_pubkey(validator_keypair.pubkey());
@ -1008,43 +1025,28 @@ mod tests {
num_ending_ticks,
);
let non_tick_active_entries_len = active_set_entries.len() - num_ending_ticks as usize;
let remaining_ticks_in_zeroth_slot = ticks_per_block - num_genesis_ticks;
let entries_for_zeroth_slot = min(
active_set_entries.len(),
non_tick_active_entries_len + remaining_ticks_in_zeroth_slot as usize,
);
let entry_chunks: Vec<_> = active_set_entries[entries_for_zeroth_slot..]
.chunks(ticks_per_block as usize)
.collect();
let blocktree = Blocktree::open(&ledger_path).unwrap();
let active_set_entries_len = active_set_entries.len() as u64;
let last_id = active_set_entries.last().unwrap().id;
// Iterate writing slots through 0..entry_chunks.len()
for i in 0..entry_chunks.len() + 1 {
let (start_height, entries) = {
if i == 0 {
(
genesis_entry_height,
&active_set_entries[..entries_for_zeroth_slot],
)
} else {
(0, entry_chunks[i - 1])
}
};
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
entry_height,
active_set_entries,
)
.unwrap();
blocktree
.write_entries(i as u64, start_height, entries)
.unwrap();
}
entry_height += active_set_entries_len;
let entry_height = genesis_entry_height + active_set_entries.len() as u64;
(
leader_node,
validator_node,
ledger_path,
entry_height,
active_set_entries.last().unwrap().id,
last_id,
)
}
}

View File

@ -387,27 +387,35 @@ mod test {
let my_node = Node::new_localhost_with_pubkey(my_id);
let cluster_info_me = ClusterInfo::new(my_node.info.clone());
// Create keypair for the old leader
let old_leader_id = Keypair::new().pubkey();
// Create a ledger
let (mint_keypair, my_ledger_path, genesis_entry_height, mut last_id, last_entry_id) =
create_tmp_sample_ledger(
"test_replay_stage_leader_rotation_exit",
10_000,
0,
old_leader_id,
500,
);
info!("my_id: {:?}", my_id);
info!("old_leader_id: {:?}", old_leader_id);
// Set up the LeaderScheduler so that my_id becomes the leader for epoch 1
let ticks_per_slot = 16;
let leader_scheduler_config = LeaderSchedulerConfig::new(ticks_per_slot, 1, ticks_per_slot);
// Create keypair for the old leader
let old_leader_id = Keypair::new().pubkey();
// Create a ledger
let (
mint_keypair,
my_ledger_path,
mut tick_height,
entry_height,
mut last_id,
last_entry_id,
) = create_tmp_sample_ledger(
"test_replay_stage_leader_rotation_exit",
10_000,
0,
old_leader_id,
500,
ticks_per_slot,
);
info!("my_id: {:?}", my_id);
info!("old_leader_id: {:?}", old_leader_id);
let my_keypair = Arc::new(my_keypair);
let num_ending_ticks = 0;
let (active_set_entries, voting_keypair) = make_active_set_entries(
&my_keypair,
&mint_keypair,
@ -415,7 +423,7 @@ mod test {
ticks_per_slot, // add a vote for tick_height = ticks_per_slot
&last_entry_id,
&last_id,
0,
num_ending_ticks,
);
last_id = active_set_entries.last().unwrap().id;
@ -424,10 +432,13 @@ mod test {
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
genesis_entry_height,
&active_set_entries,
tick_height,
ticks_per_slot,
entry_height,
active_set_entries,
)
.unwrap();
tick_height += num_ending_ticks;
}
{
@ -466,7 +477,13 @@ mod test {
// Write the entries to the ledger, replay_stage should get notified of changes
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, meta.consumed, &entries_to_send)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
meta.consumed,
&entries_to_send,
)
.unwrap();
info!("Wait for replay_stage to exit and check return value is correct");
@ -508,14 +525,22 @@ mod test {
// Create keypair for the leader
let leader_id = Keypair::new().pubkey();
let (_mint_keypair, my_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"test_vote_error_replay_stage_correctness",
10_000,
1,
leader_id,
500,
);
let ticks_per_slot = std::u64::MAX;
let (
_mint_keypair,
my_ledger_path,
tick_height,
_last_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
"test_vote_error_replay_stage_correctness",
10_000,
1,
leader_id,
500,
ticks_per_slot,
);
// Set up the cluster info
let cluster_info_me = Arc::new(RwLock::new(ClusterInfo::new(my_node.info.clone())));
@ -555,9 +580,14 @@ mod test {
info!("Send ReplayStage an entry, should see it on the ledger writer receiver");
let next_tick = create_ticks(1, last_entry_id);
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, entry_height, next_tick.clone())
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
entry_height,
next_tick.clone(),
)
.unwrap();
let received_tick = ledger_writer_recv
@ -586,15 +616,23 @@ mod test {
// Create keypair for the leader
let leader_id = Keypair::new().pubkey();
let ticks_per_slot = 10;
// Create the ledger
let (mint_keypair, my_ledger_path, genesis_entry_height, last_id, last_entry_id) =
create_tmp_sample_ledger(
"test_vote_error_replay_stage_leader_rotation",
10_000,
1,
leader_id,
500,
);
let (
mint_keypair,
my_ledger_path,
tick_height,
genesis_entry_height,
last_id,
last_entry_id,
) = create_tmp_sample_ledger(
"test_vote_error_replay_stage_leader_rotation",
10_000,
1,
leader_id,
500,
ticks_per_slot,
);
let my_keypair = Arc::new(my_keypair);
// Write two entries to the ledger so that the validator is in the active set:
@ -610,20 +648,19 @@ mod test {
0,
);
let mut last_id = active_set_entries.last().unwrap().id;
let initial_tick_height = genesis_entry_height;
{
let blocktree = Blocktree::open(&my_ledger_path).unwrap();
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&active_set_entries,
)
.unwrap();
}
let ticks_per_slot = 10;
let slots_per_epoch = 2;
let active_window_tick_length = ticks_per_slot * slots_per_epoch;
let leader_scheduler_config =
@ -667,11 +704,10 @@ mod test {
cluster_info_me.write().unwrap().push_vote(vote);
// Send enough ticks to trigger leader rotation
let total_entries_to_send = (active_window_tick_length - initial_tick_height) as usize;
let total_entries_to_send = (active_window_tick_length - tick_height) as usize;
let num_hashes = 1;
let leader_rotation_index =
(active_window_tick_length - initial_tick_height - 1) as usize;
let leader_rotation_index = (active_window_tick_length - tick_height - 1) as usize;
let mut expected_last_id = Hash::default();
for i in 0..total_entries_to_send {
let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]);
@ -679,6 +715,8 @@ mod test {
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height + i as u64,
ticks_per_slot,
meta.consumed + i as u64,
vec![entry.clone()],
)

View File

@ -491,20 +491,28 @@ mod tests {
solana_logger::setup();
let keypair = Arc::new(Keypair::new());
let exit = Arc::new(AtomicBool::new(false));
let ticks_per_slot = std::u64::MAX;
let (_mint, ledger_path, genesis_entry_height, _last_id, _last_entry_id) =
let (_mint, ledger_path, tick_height, genesis_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"storage_stage_process_entries",
1000,
1,
Keypair::new().pubkey(),
1,
ticks_per_slot,
);
let entries = make_tiny_test_entries(64);
let blocktree = Blocktree::open(&ledger_path).unwrap();
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, genesis_entry_height, &entries)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&entries,
)
.unwrap();
let cluster_info = test_cluster_info(keypair.pubkey());
@ -560,20 +568,28 @@ mod tests {
solana_logger::setup();
let keypair = Arc::new(Keypair::new());
let exit = Arc::new(AtomicBool::new(false));
let ticks_per_slot = std::u64::MAX;
let (_mint, ledger_path, genesis_entry_height, _last_id, _last_entry_id) =
let (_mint, ledger_path, tick_height, genesis_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"storage_stage_process_entries",
1000,
1,
Keypair::new().pubkey(),
1,
ticks_per_slot,
);
let entries = make_tiny_test_entries(128);
let blocktree = Blocktree::open(&ledger_path).unwrap();
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, genesis_entry_height, &entries)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&entries,
)
.unwrap();
let cluster_info = test_cluster_info(keypair.pubkey());

View File

@ -464,8 +464,16 @@ pub fn new_fullnode(ledger_name: &'static str) -> (Fullnode, NodeInfo, Keypair,
let node = Node::new_localhost_with_pubkey(node_keypair.pubkey());
let node_info = node.info.clone();
let (mint_keypair, ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(ledger_name, 10_000, 0, node_info.id, 42);
let fullnode_config = &FullnodeConfig::default();
let (mint_keypair, ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
ledger_name,
10_000,
0,
node_info.id,
42,
fullnode_config.leader_scheduler_config.ticks_per_slot,
);
let vote_account_keypair = Arc::new(Keypair::new());
let voting_keypair = VotingKeypair::new_local(&vote_account_keypair);

View File

@ -44,19 +44,31 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
let bob_pubkey = Keypair::new().pubkey();
let mut ledger_paths = Vec::new();
let (alice, leader_ledger_path, mut last_entry_height, _last_id, mut last_entry_id) =
create_tmp_sample_ledger("multi_node_ledger_window", 10_000, 0, leader_data.id, 500);
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (
alice,
leader_ledger_path,
tick_height,
mut last_entry_height,
_last_id,
mut last_entry_id,
) = create_tmp_sample_ledger(
"multi_node_ledger_window",
10_000,
0,
leader_data.id,
500,
ticks_per_slot,
);
ledger_paths.push(leader_ledger_path.clone());
// make a copy at zero
let zero_ledger_path = tmp_copy_ledger(&leader_ledger_path, "multi_node_ledger_window");
ledger_paths.push(zero_ledger_path.clone());
let fullnode_config = FullnodeConfig::default();
info!(
"ticks_per_slot: {}",
fullnode_config.leader_scheduler_config.ticks_per_slot
);
info!("ticks_per_slot: {}", ticks_per_slot,);
// Write some into leader's ledger, this should populate the leader's window
// and force it to respond to repair from the ledger window
@ -69,7 +81,13 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
last_entry_id,
);
blocktree
.write_entries(0, last_entry_height, &entries)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
last_entry_height,
&entries,
)
.unwrap();
last_entry_height += entries.len() as u64;
@ -164,13 +182,17 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
let bob_pubkey = Keypair::new().pubkey();
let mut ledger_paths = Vec::new();
let (alice, genesis_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (alice, genesis_ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"multi_node_validator_catchup_from_zero",
10_000,
0,
leader_data.id,
500,
ticks_per_slot,
);
ledger_paths.push(genesis_ledger_path.clone());
@ -192,7 +214,7 @@ fn test_multi_node_validator_catchup_from_zero() -> result::Result<()> {
&leader_ledger_path,
voting_keypair,
None,
&FullnodeConfig::default(),
&fullnode_config,
);
let mut node_exits = vec![server.run(None)];
@ -347,15 +369,24 @@ fn test_multi_node_basic() {
const N: usize = 5;
trace!("test_multi_node_basic");
let fullnode_config = FullnodeConfig::default();
let leader_keypair = Arc::new(Keypair::new());
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let leader_data = leader.info.clone();
let bob_pubkey = Keypair::new().pubkey();
let mut ledger_paths = Vec::new();
let (alice, genesis_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger("multi_node_basic", 10_000, 0, leader_data.id, 500);
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (alice, genesis_ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"multi_node_basic",
10_000,
0,
leader_data.id,
500,
ticks_per_slot,
);
ledger_paths.push(genesis_ledger_path.clone());
let leader_ledger_path = tmp_copy_ledger(&genesis_ledger_path, "multi_node_basic");
@ -454,8 +485,17 @@ fn test_boot_validator_from_file() -> result::Result<()> {
let bob_pubkey = Keypair::new().pubkey();
let mut ledger_paths = Vec::new();
let (alice, genesis_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger("boot_validator_from_file", 100_000, 0, leader_pubkey, 1000);
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (alice, genesis_ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"boot_validator_from_file",
100_000,
0,
leader_pubkey,
1000,
ticks_per_slot,
);
ledger_paths.push(genesis_ledger_path.clone());
let leader_ledger_path = tmp_copy_ledger(&genesis_ledger_path, "multi_node_basic");
@ -469,7 +509,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
&leader_ledger_path,
voting_keypair,
None,
&FullnodeConfig::default(),
&fullnode_config,
);
let leader_balance =
send_tx_and_retry_get_balance(&leader_data, &alice, &bob_pubkey, 500, Some(500)).unwrap();
@ -490,7 +530,7 @@ fn test_boot_validator_from_file() -> result::Result<()> {
&ledger_path,
voting_keypair,
Some(&leader_data),
&FullnodeConfig::default(),
&fullnode_config,
);
let mut client = mk_client(&validator_data);
let getbal = retry_get_balance(&mut client, &bob_pubkey, Some(leader_balance));
@ -533,13 +573,16 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
let leader_keypair = Arc::new(Keypair::new());
let initial_leader_balance = 500;
let (alice, ledger_path, _last_entry_height, _last_id, _last_entry_id) =
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (alice, ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"leader_restart_validator_start_from_old_ledger",
100_000 + 500 * solana::window_service::MAX_REPAIR_BACKOFF as u64,
0,
leader_keypair.pubkey(),
initial_leader_balance,
ticks_per_slot,
);
let bob_pubkey = Keypair::new().pubkey();
@ -595,7 +638,7 @@ fn test_leader_restart_validator_start_from_old_ledger() -> result::Result<()> {
&stale_ledger_path,
voting_keypair,
Some(&leader_data),
&FullnodeConfig::default(),
&fullnode_config,
);
// trigger broadcast, validator should catch up from leader, whose window contains
@ -643,13 +686,16 @@ fn test_multi_node_dynamic_network() {
let leader_pubkey = leader_keypair.pubkey().clone();
let leader = Node::new_localhost_with_pubkey(leader_keypair.pubkey());
let bob_pubkey = Keypair::new().pubkey();
let (alice, genesis_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
let fullnode_config = FullnodeConfig::default();
let ticks_per_slot = fullnode_config.leader_scheduler_config.ticks_per_slot;
let (alice, genesis_ledger_path, _tick_height, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(
"multi_node_dynamic_network",
10_000_000,
0,
leader_pubkey,
500,
ticks_per_slot,
);
let mut ledger_paths = Vec::new();
@ -668,7 +714,7 @@ fn test_multi_node_dynamic_network() {
&leader_ledger_path,
voting_keypair,
None,
&FullnodeConfig::default(),
&fullnode_config,
);
let server_exit = server.run(None);
info!(
@ -865,18 +911,25 @@ fn test_leader_to_validator_transition() {
// Initialize the leader ledger. Make a mint and a genesis entry
// in the leader ledger
let (mint_keypair, leader_ledger_path, genesis_entry_height, last_id, last_entry_id) =
create_tmp_sample_ledger(
"test_leader_to_validator_transition",
10_000,
0,
leader_info.id,
500,
);
let (
mint_keypair,
leader_ledger_path,
tick_height,
genesis_entry_height,
last_id,
last_entry_id,
) = create_tmp_sample_ledger(
"test_leader_to_validator_transition",
10_000,
0,
leader_info.id,
500,
ticks_per_slot,
);
// Write the votes entries to the ledger that will cause leader rotation
// to validator_keypair at slot 2
let (bootstrap_entries, _) = make_active_set_entries(
let (active_set_entries, _) = make_active_set_entries(
&validator_keypair,
&mint_keypair,
100,
@ -890,8 +943,10 @@ fn test_leader_to_validator_transition() {
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&bootstrap_entries,
&active_set_entries,
)
.unwrap();
}
@ -959,15 +1014,31 @@ fn test_leader_validator_basic() {
info!("leader id: {}", leader_keypair.pubkey());
info!("validator id: {}", validator_keypair.pubkey());
// Create the leader scheduler config
let mut fullnode_config = FullnodeConfig::default();
let ticks_per_slot = 5;
fullnode_config.leader_scheduler_config = LeaderSchedulerConfig::new(
ticks_per_slot,
1, // 1 slot per epoch
ticks_per_slot,
);
// Make a common mint and a genesis entry for both leader + validator ledgers
let (mint_keypair, leader_ledger_path, genesis_entry_height, last_id, last_entry_id) =
create_tmp_sample_ledger(
"test_leader_validator_basic",
10_000,
0,
leader_info.id,
500,
);
let (
mint_keypair,
leader_ledger_path,
tick_height,
genesis_entry_height,
last_id,
last_entry_id,
) = create_tmp_sample_ledger(
"test_leader_validator_basic",
10_000,
0,
leader_info.id,
500,
ticks_per_slot,
);
// Add validator vote on tick height 1
let (active_set_entries, _) = make_active_set_entries(
@ -984,6 +1055,8 @@ fn test_leader_validator_basic() {
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&active_set_entries,
)
@ -996,15 +1069,6 @@ fn test_leader_validator_basic() {
let validator_ledger_path = tmp_copy_ledger(&leader_ledger_path, "test_leader_validator_basic");
ledger_paths.push(validator_ledger_path.clone());
// Create the leader scheduler config
let mut fullnode_config = FullnodeConfig::default();
let ticks_per_slot = 5;
fullnode_config.leader_scheduler_config = LeaderSchedulerConfig::new(
ticks_per_slot,
1, // 1 slot per epoch
ticks_per_slot,
);
// Start the validator node
let voting_keypair = VotingKeypair::new_local(&validator_keypair);
let validator = Fullnode::new(
@ -1113,14 +1177,21 @@ fn test_dropped_handoff_recovery() {
// Make a common mint and a genesis entry for both leader + validator's ledgers
let num_ending_ticks = 1;
let (mint_keypair, genesis_ledger_path, genesis_entry_height, last_id, last_entry_id) =
create_tmp_sample_ledger(
"test_dropped_handoff_recovery",
10_000,
num_ending_ticks,
bootstrap_leader_info.id,
500,
);
let (
mint_keypair,
genesis_ledger_path,
tick_height,
genesis_entry_height,
last_id,
last_entry_id,
) = create_tmp_sample_ledger(
"test_dropped_handoff_recovery",
10_000,
num_ending_ticks,
bootstrap_leader_info.id,
500,
ticks_per_slot,
);
// Create the validator keypair that will be the next leader in line
let next_leader_keypair = Arc::new(Keypair::new());
@ -1149,6 +1220,8 @@ fn test_dropped_handoff_recovery() {
blocktree
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
genesis_entry_height,
&active_set_entries,
)
@ -1256,6 +1329,14 @@ fn test_full_leader_validator_network() {
// The number of validators
const N: usize = 2;
// Create the common leader scheduling configuration
let slots_per_epoch = (N + 1) as u64;
let ticks_per_slot = 5;
let ticks_per_epoch = slots_per_epoch * ticks_per_slot;
let mut fullnode_config = FullnodeConfig::default();
fullnode_config.leader_scheduler_config =
LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, ticks_per_epoch * 3);
// Create the bootstrap leader node information
let bootstrap_leader_keypair = Arc::new(Keypair::new());
info!("bootstrap leader: {:?}", bootstrap_leader_keypair.pubkey());
@ -1275,7 +1356,8 @@ fn test_full_leader_validator_network() {
let (
mint_keypair,
bootstrap_leader_ledger_path,
genesis_entry_height,
tick_height,
mut entry_height,
last_id,
mut last_entry_id,
) = create_tmp_sample_ledger(
@ -1284,6 +1366,7 @@ fn test_full_leader_validator_network() {
num_ending_ticks,
bootstrap_leader_info.id,
500,
ticks_per_slot,
);
// Create a common ledger with entries in the beginnging that will add all the validators
@ -1291,11 +1374,10 @@ fn test_full_leader_validator_network() {
let mut ledger_paths = Vec::new();
ledger_paths.push(bootstrap_leader_ledger_path.clone());
let mut index = genesis_entry_height;
for node_keypair in node_keypairs.iter() {
// Make entries to give each validator node some stake so that they will be in the
// leader election active set
let (bootstrap_entries, _) = make_active_set_entries(
let (active_set_entries, _) = make_active_set_entries(
node_keypair,
&mint_keypair,
100,
@ -1306,27 +1388,25 @@ fn test_full_leader_validator_network() {
);
// Write the entries
last_entry_id = bootstrap_entries
last_entry_id = active_set_entries
.last()
.expect("expected at least one genesis entry")
.id;
{
let blocktree = Blocktree::open(&bootstrap_leader_ledger_path).unwrap();
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, index, &bootstrap_entries)
.write_entries(
DEFAULT_SLOT_HEIGHT,
tick_height,
ticks_per_slot,
entry_height,
&active_set_entries,
)
.unwrap();
index += bootstrap_entries.len() as u64;
entry_height += active_set_entries.len() as u64;
}
}
// Create the common leader scheduling configuration
let slots_per_epoch = (N + 1) as u64;
let ticks_per_slot = 5;
let ticks_per_epoch = slots_per_epoch * ticks_per_slot;
let mut fullnode_config = FullnodeConfig::default();
fullnode_config.leader_scheduler_config =
LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, ticks_per_epoch * 3);
let mut nodes = vec![];
info!("Start up the validators");
@ -1477,10 +1557,20 @@ fn test_broadcast_last_tick() {
let bootstrap_leader_node = Node::new_localhost_with_pubkey(bootstrap_leader_keypair.pubkey());
let bootstrap_leader_info = bootstrap_leader_node.info.clone();
// Create the fullnode configuration
let ticks_per_slot = 40;
let slots_per_epoch = 2;
let ticks_per_epoch = slots_per_epoch * ticks_per_slot;
let mut fullnode_config = FullnodeConfig::default();
fullnode_config.leader_scheduler_config =
LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, ticks_per_epoch);
// Create leader ledger
let (
_mint_keypair,
bootstrap_leader_ledger_path,
_tick_height,
genesis_entry_height,
_last_id,
_last_entry_id,
@ -1490,6 +1580,7 @@ fn test_broadcast_last_tick() {
0,
bootstrap_leader_info.id,
500,
ticks_per_slot,
);
let genesis_ledger_len = genesis_entry_height;
@ -1516,16 +1607,10 @@ fn test_broadcast_last_tick() {
})
.collect();
let ticks_per_slot = 40;
let slots_per_epoch = 2;
let ticks_per_epoch = slots_per_epoch * ticks_per_slot;
// Start up the bootstrap leader fullnode
let bootstrap_leader_keypair = Arc::new(bootstrap_leader_keypair);
let voting_keypair = VotingKeypair::new_local(&bootstrap_leader_keypair);
let mut fullnode_config = FullnodeConfig::default();
fullnode_config.leader_scheduler_config =
LeaderSchedulerConfig::new(ticks_per_slot, slots_per_epoch, ticks_per_epoch);
let bootstrap_leader = Fullnode::new(
bootstrap_leader_node,
&bootstrap_leader_keypair,

View File

@ -40,8 +40,22 @@ fn test_replicator_startup_basic() {
let leader_info = leader_node.info.clone();
let leader_ledger_path = "replicator_test_leader_ledger";
let (mint_keypair, leader_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(leader_ledger_path, 1_000_000_000, 0, leader_info.id, 42);
let mut fullnode_config = FullnodeConfig::default();
let (
mint_keypair,
leader_ledger_path,
_tick_height,
_last_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
leader_ledger_path,
1_000_000_000,
0,
leader_info.id,
42,
fullnode_config.leader_scheduler_config.ticks_per_slot,
);
let validator_ledger_path =
tmp_copy_ledger(&leader_ledger_path, "replicator_test_validator_ledger");
@ -49,7 +63,6 @@ fn test_replicator_startup_basic() {
{
let voting_keypair = VotingKeypair::new_local(&leader_keypair);
let mut fullnode_config = FullnodeConfig::default();
fullnode_config.storage_rotate_count = STORAGE_ROTATE_TEST_COUNT;
let leader = Fullnode::new(
leader_node,
@ -277,8 +290,22 @@ fn test_replicator_startup_ledger_hang() {
let leader_info = leader_node.info.clone();
let leader_ledger_path = "replicator_test_leader_ledger";
let (_mint_keypair, leader_ledger_path, _last_entry_height, _last_id, _last_entry_id) =
create_tmp_sample_ledger(leader_ledger_path, 100, 0, leader_info.id, 42);
let fullnode_config = FullnodeConfig::default();
let (
_mint_keypair,
leader_ledger_path,
_tick_height,
_last_entry_height,
_last_id,
_last_entry_id,
) = create_tmp_sample_ledger(
leader_ledger_path,
100,
0,
leader_info.id,
42,
fullnode_config.leader_scheduler_config.ticks_per_slot,
);
let validator_ledger_path =
tmp_copy_ledger(&leader_ledger_path, "replicator_test_validator_ledger");
@ -292,7 +319,7 @@ fn test_replicator_startup_ledger_hang() {
&leader_ledger_path,
voting_keypair,
None,
&FullnodeConfig::default(),
&fullnode_config,
);
let validator_keypair = Arc::new(Keypair::new());