Add test demonstrating that process_blocktree()'s implementation is lacking

This commit is contained in:
Michael Vines 2019-02-19 19:40:23 -08:00
parent 94f9ac0332
commit 8daba3e563
2 changed files with 112 additions and 10 deletions

View File

@ -1339,12 +1339,10 @@ pub fn create_tmp_sample_ledger(
let entries = crate::entry::create_ticks(num_extra_ticks, last_entry_id);
let blocktree = Blocktree::open_config(&ledger_path, config).unwrap();
// create_new_ledger creates one beginning tick
tick_height += num_extra_ticks;
blocktree
.write_entries(DEFAULT_SLOT_HEIGHT, tick_height, entry_height, &entries)
.unwrap();
tick_height += num_extra_ticks;
entry_height += entries.len() as u64;
last_id = entries.last().unwrap().id;
last_entry_id = last_id;
@ -2408,12 +2406,7 @@ pub mod tests {
Blocktree::destroy(&blocktree_path).expect("Expected successful database destruction");
}
pub fn make_slot_entries(
slot_height: u64,
parent_slot: u64,
num_entries: u64,
) -> (Vec<Blob>, Vec<Entry>) {
let entries = make_tiny_test_entries(num_entries as usize);
pub fn entries_to_blobs(entries: &Vec<Entry>, slot_height: u64, parent_slot: u64) -> Vec<Blob> {
let mut blobs = entries.clone().to_blobs();
for (i, b) in blobs.iter_mut().enumerate() {
b.set_index(i as u64);
@ -2422,6 +2415,16 @@ pub mod tests {
}
blobs.last_mut().unwrap().set_is_last_in_slot();
blobs
}
pub fn make_slot_entries(
slot_height: u64,
parent_slot: u64,
num_entries: u64,
) -> (Vec<Blob>, Vec<Entry>) {
let entries = make_tiny_test_entries(num_entries as usize);
let blobs = entries_to_blobs(&entries, slot_height, parent_slot);
(blobs, entries)
}

View File

@ -225,13 +225,112 @@ pub fn process_blocktree(
#[cfg(test)]
mod tests {
use super::*;
use crate::entry::{next_entries, next_entry, Entry};
use crate::blocktree::tests::entries_to_blobs;
use crate::blocktree::{create_tmp_sample_ledger, BlocktreeConfig};
use crate::entry::{create_ticks, next_entries, next_entry, Entry};
use crate::gen_keys::GenKeys;
use solana_sdk::genesis_block::GenesisBlock;
use solana_sdk::native_program::ProgramError;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_transaction::SystemTransaction;
fn fill_blocktree_slot_with_ticks(
blocktree: &Blocktree,
blocktree_config: &BlocktreeConfig,
slot: u64,
parent_slot: u64,
last_entry_id: Hash,
) -> Hash {
let entries = create_ticks(blocktree_config.ticks_per_slot, last_entry_id);
let last_entry_id = entries.last().unwrap().id;
let blobs = entries_to_blobs(&entries, slot, parent_slot);
blocktree.insert_data_blobs(blobs.iter()).unwrap();
last_entry_id
}
#[test]
fn test_process_blocktree_with_two_forks() {
solana_logger::setup();
let leader_scheduler = Arc::new(RwLock::new(LeaderScheduler::default()));
let blocktree_config = &BlocktreeConfig::default();
// Create a new ledger with slot 0 full of ticks
let (
_mint_keypair,
ledger_path,
tick_height,
_last_entry_height,
_last_id,
mut last_entry_id,
) = create_tmp_sample_ledger(
"blocktree_with_two_forks",
10_000,
blocktree_config.ticks_per_slot - 1,
Keypair::new().pubkey(),
123,
&blocktree_config,
);
debug!("ledger_path: {:?}", ledger_path);
assert_eq!(tick_height, blocktree_config.ticks_per_slot);
/*
Build a blocktree in the ledger with the following fork structure:
slot 0
|
slot 1
/ \
slot 2 |
/ |
slot 3 |
|
slot 4
*/
let genesis_block =
GenesisBlock::load(&ledger_path).expect("Expected to successfully open genesis block");
let (blocktree, _ledger_signal_receiver) =
Blocktree::open_with_config_signal(&ledger_path, &blocktree_config)
.expect("Expected to successfully open database ledger");
// Fork 1, ending at slot 3
let last_slot1_entry_id =
fill_blocktree_slot_with_ticks(&blocktree, &blocktree_config, 1, 0, last_entry_id);
last_entry_id = fill_blocktree_slot_with_ticks(
&blocktree,
&blocktree_config,
2,
1,
last_slot1_entry_id,
);
let last_fork1_entry_id =
fill_blocktree_slot_with_ticks(&blocktree, &blocktree_config, 3, 2, last_entry_id);
// Fork 2, ending at slot 4
let last_fork2_entry_id = fill_blocktree_slot_with_ticks(
&blocktree,
&blocktree_config,
4,
1,
last_slot1_entry_id,
);
info!("last_fork1_entry_id: {:?}", last_fork1_entry_id);
info!("last_fork2_entry_id: {:?}", last_fork2_entry_id);
let (bank_forks, ledger_height, last_entry_id) =
process_blocktree(&genesis_block, &blocktree, &leader_scheduler).unwrap();
// The following asserts loosely demonstrate how `process_blocktree()` currently only
// processes fork1 and ignores fork2.
assert_eq!(last_entry_id, last_fork1_entry_id);
assert_eq!(ledger_height, 4 * blocktree_config.ticks_per_slot);
assert_eq!(bank_forks.working_bank().last_id(), last_entry_id);
}
#[test]
fn test_first_err() {
assert_eq!(first_err(&[Ok(())]), Ok(()));