Move virtual genesis tick into the ledger proper as entry 0
This commit is contained in:
parent
9e9c82869a
commit
c01290438f
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use clap::{crate_version, value_t_or_exit, App, Arg};
|
use clap::{crate_version, value_t_or_exit, App, Arg};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use solana::db_ledger::create_empty_ledger;
|
use solana::db_ledger::create_new_ledger;
|
||||||
use solana::genesis_block::GenesisBlock;
|
use solana::genesis_block::GenesisBlock;
|
||||||
use solana_sdk::signature::{read_keypair, KeypairUtil};
|
use solana_sdk::signature::{read_keypair, KeypairUtil};
|
||||||
use std::error;
|
use std::error;
|
||||||
|
@ -74,6 +74,6 @@ fn main() -> Result<(), Box<dyn error::Error>> {
|
||||||
bootstrap_leader_tokens: BOOTSTRAP_LEADER_TOKENS,
|
bootstrap_leader_tokens: BOOTSTRAP_LEADER_TOKENS,
|
||||||
};
|
};
|
||||||
|
|
||||||
create_empty_ledger(ledger_path, &genesis_block)?;
|
create_new_ledger(ledger_path, &genesis_block)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ fn bad_arguments() {
|
||||||
fn nominal() {
|
fn nominal() {
|
||||||
let keypair = Arc::new(Keypair::new());
|
let keypair = Arc::new(Keypair::new());
|
||||||
let (_, ledger_path, _, _) =
|
let (_, ledger_path, _, _) =
|
||||||
create_tmp_sample_ledger("test_ledger_tool_nominal", 100, 10, keypair.pubkey(), 50);
|
create_tmp_sample_ledger("test_ledger_tool_nominal", 100, 9, keypair.pubkey(), 50);
|
||||||
|
|
||||||
// Basic validation
|
// Basic validation
|
||||||
let output = run_ledger_tool(&["-l", &ledger_path, "verify"]);
|
let output = run_ledger_tool(&["-l", &ledger_path, "verify"]);
|
||||||
|
|
77
src/bank.rs
77
src/bank.rs
|
@ -724,15 +724,19 @@ impl Bank {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append entry blocks to the ledger, verifying them along the way.
|
/// Starting from the genesis block, append the provided entries to the ledger verifying them
|
||||||
pub fn process_ledger<I>(&self, entries: I) -> Result<(u64, Hash)>
|
/// along the way.
|
||||||
|
pub fn process_ledger<I>(
|
||||||
|
&mut self,
|
||||||
|
genesis_block: &GenesisBlock,
|
||||||
|
entries: I,
|
||||||
|
) -> Result<(u64, Hash)>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Entry>,
|
I: IntoIterator<Item = Entry>,
|
||||||
{
|
{
|
||||||
// these magic numbers are from genesis of the mint, could pull them
|
|
||||||
// back out of this loop.
|
|
||||||
let mut entry_height = 0;
|
let mut entry_height = 0;
|
||||||
let mut last_id = self.last_id();
|
let mut last_id = genesis_block.last_id();
|
||||||
|
self.last_ids = RwLock::new(StatusDeque::default());
|
||||||
|
|
||||||
// Ledger verification needs to be parallelized, but we can't pull the whole
|
// Ledger verification needs to be parallelized, but we can't pull the whole
|
||||||
// thing into memory. We therefore chunk it.
|
// thing into memory. We therefore chunk it.
|
||||||
|
@ -1162,9 +1166,14 @@ mod tests {
|
||||||
mint_keypair: &Keypair,
|
mint_keypair: &Keypair,
|
||||||
keypairs: &[Keypair],
|
keypairs: &[Keypair],
|
||||||
) -> impl Iterator<Item = Entry> {
|
) -> impl Iterator<Item = Entry> {
|
||||||
let mut last_id = genesis_block.last_id();
|
|
||||||
let mut hash = genesis_block.last_id();
|
|
||||||
let mut entries: Vec<Entry> = vec![];
|
let mut entries: Vec<Entry> = vec![];
|
||||||
|
|
||||||
|
// Start off the ledger with a tick linked to the genesis block
|
||||||
|
let tick = Entry::new(&genesis_block.last_id(), 0, 1, vec![]);
|
||||||
|
let mut hash = tick.id;
|
||||||
|
let mut last_id = tick.id;
|
||||||
|
entries.push(tick);
|
||||||
|
|
||||||
let num_hashes = 1;
|
let num_hashes = 1;
|
||||||
for k in keypairs {
|
for k in keypairs {
|
||||||
let txs = vec![Transaction::system_new(
|
let txs = vec![Transaction::system_new(
|
||||||
|
@ -1184,18 +1193,24 @@ mod tests {
|
||||||
entries.into_iter()
|
entries.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a ledger with tick entries every `ticks` entries
|
// create a ledger with a tick every `tick_interval` entries and a couple other transactions
|
||||||
fn create_sample_block_with_ticks(
|
fn create_sample_block_with_ticks(
|
||||||
genesis_block: &GenesisBlock,
|
genesis_block: &GenesisBlock,
|
||||||
mint_keypair: &Keypair,
|
mint_keypair: &Keypair,
|
||||||
length: usize,
|
num_entries: usize,
|
||||||
ticks: usize,
|
tick_interval: usize,
|
||||||
) -> impl Iterator<Item = Entry> {
|
) -> impl Iterator<Item = Entry> {
|
||||||
let mut entries = Vec::with_capacity(length);
|
assert!(num_entries > 0);
|
||||||
let mut last_id = genesis_block.last_id();
|
let mut entries = Vec::with_capacity(num_entries);
|
||||||
let mut hash = genesis_block.last_id();
|
|
||||||
|
// Start off the ledger with a tick linked to the genesis block
|
||||||
|
let tick = Entry::new(&genesis_block.last_id(), 0, 1, vec![]);
|
||||||
|
let mut hash = tick.id;
|
||||||
|
let mut last_id = tick.id;
|
||||||
|
entries.push(tick);
|
||||||
|
|
||||||
let num_hashes = 1;
|
let num_hashes = 1;
|
||||||
for i in 0..length {
|
for i in 1..num_entries {
|
||||||
let keypair = Keypair::new();
|
let keypair = Keypair::new();
|
||||||
let tx = Transaction::system_new(mint_keypair, keypair.pubkey(), 1, last_id);
|
let tx = Transaction::system_new(mint_keypair, keypair.pubkey(), 1, last_id);
|
||||||
let entry = Entry::new(&hash, 0, num_hashes, vec![tx]);
|
let entry = Entry::new(&hash, 0, num_hashes, vec![tx]);
|
||||||
|
@ -1210,7 +1225,7 @@ mod tests {
|
||||||
hash = entry.id;
|
hash = entry.id;
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
|
|
||||||
if (i + 1) % ticks == 0 {
|
if (i + 1) % tick_interval == 0 {
|
||||||
let tick = Entry::new(&hash, 0, num_hashes, vec![]);
|
let tick = Entry::new(&hash, 0, num_hashes, vec![]);
|
||||||
hash = tick.id;
|
hash = tick.id;
|
||||||
last_id = hash;
|
last_id = hash;
|
||||||
|
@ -1220,27 +1235,31 @@ mod tests {
|
||||||
entries.into_iter()
|
entries.into_iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_sample_ledger(length: usize) -> (GenesisBlock, Keypair, impl Iterator<Item = Entry>) {
|
fn create_sample_ledger(
|
||||||
|
tokens: u64,
|
||||||
|
num_entries: usize,
|
||||||
|
) -> (GenesisBlock, Keypair, impl Iterator<Item = Entry>) {
|
||||||
let mint_keypair = Keypair::new();
|
let mint_keypair = Keypair::new();
|
||||||
let genesis_block = GenesisBlock {
|
let genesis_block = GenesisBlock {
|
||||||
bootstrap_leader_id: Keypair::new().pubkey(),
|
bootstrap_leader_id: Keypair::new().pubkey(),
|
||||||
bootstrap_leader_tokens: 1,
|
bootstrap_leader_tokens: 1,
|
||||||
mint_id: mint_keypair.pubkey(),
|
mint_id: mint_keypair.pubkey(),
|
||||||
tokens: length as u64 + 2,
|
tokens,
|
||||||
};
|
};
|
||||||
let block = create_sample_block_with_ticks(&genesis_block, &mint_keypair, length, length);
|
let block =
|
||||||
|
create_sample_block_with_ticks(&genesis_block, &mint_keypair, num_entries, num_entries);
|
||||||
(genesis_block, mint_keypair, block)
|
(genesis_block, mint_keypair, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_process_ledger_simple() {
|
fn test_process_ledger_simple() {
|
||||||
let (genesis_block, mint_keypair, ledger) = create_sample_ledger(1);
|
let (genesis_block, mint_keypair, ledger) = create_sample_ledger(100, 2);
|
||||||
let bank = Bank::default();
|
let mut bank = Bank::default();
|
||||||
bank.process_genesis_block(&genesis_block);
|
bank.process_genesis_block(&genesis_block);
|
||||||
bank.add_system_program();
|
bank.add_system_program();
|
||||||
let (ledger_height, last_id) = bank.process_ledger(ledger).unwrap();
|
let (ledger_height, last_id) = bank.process_ledger(&genesis_block, ledger).unwrap();
|
||||||
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 1);
|
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 98);
|
||||||
assert_eq!(ledger_height, 3);
|
assert_eq!(ledger_height, 4);
|
||||||
assert_eq!(bank.tick_height(), 2);
|
assert_eq!(bank.tick_height(), 2);
|
||||||
assert_eq!(bank.last_id(), last_id);
|
assert_eq!(bank.last_id(), last_id);
|
||||||
}
|
}
|
||||||
|
@ -1268,14 +1287,14 @@ mod tests {
|
||||||
&keypairs,
|
&keypairs,
|
||||||
);
|
);
|
||||||
|
|
||||||
let bank0 = Bank::default();
|
let mut bank0 = Bank::default();
|
||||||
bank0.add_system_program();
|
bank0.add_system_program();
|
||||||
bank0.process_genesis_block(&genesis_block);
|
bank0.process_genesis_block(&genesis_block);
|
||||||
bank0.process_ledger(ledger0).unwrap();
|
bank0.process_ledger(&genesis_block, ledger0).unwrap();
|
||||||
let bank1 = Bank::default();
|
let mut bank1 = Bank::default();
|
||||||
bank1.add_system_program();
|
bank1.add_system_program();
|
||||||
bank1.process_genesis_block(&genesis_block);
|
bank1.process_genesis_block(&genesis_block);
|
||||||
bank1.process_ledger(ledger1).unwrap();
|
bank1.process_ledger(&genesis_block, ledger1).unwrap();
|
||||||
|
|
||||||
let initial_state = bank0.hash_internal_state();
|
let initial_state = bank0.hash_internal_state();
|
||||||
|
|
||||||
|
@ -1283,11 +1302,11 @@ mod tests {
|
||||||
|
|
||||||
let pubkey = keypairs[0].pubkey();
|
let pubkey = keypairs[0].pubkey();
|
||||||
bank0
|
bank0
|
||||||
.transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id())
|
.transfer(1_000, &mint_keypair, pubkey, bank0.last_id())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_ne!(bank0.hash_internal_state(), initial_state);
|
assert_ne!(bank0.hash_internal_state(), initial_state);
|
||||||
bank1
|
bank1
|
||||||
.transfer(1_000, &mint_keypair, pubkey, genesis_block.last_id())
|
.transfer(1_000, &mint_keypair, pubkey, bank1.last_id())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state());
|
assert_eq!(bank0.hash_internal_state(), bank1.hash_internal_state());
|
||||||
}
|
}
|
||||||
|
|
|
@ -830,11 +830,16 @@ impl Iterator for EntryIterator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_empty_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Result<(u64, Hash)> {
|
pub fn create_new_ledger(ledger_path: &str, genesis_block: &GenesisBlock) -> Result<(u64, Hash)> {
|
||||||
DbLedger::destroy(ledger_path)?;
|
DbLedger::destroy(ledger_path)?;
|
||||||
DbLedger::open(ledger_path)?;
|
|
||||||
genesis_block.write(&ledger_path)?;
|
genesis_block.write(&ledger_path)?;
|
||||||
Ok((0, genesis_block.last_id()))
|
|
||||||
|
// Add a single tick linked back to the genesis_block to bootstrap the ledger
|
||||||
|
let db_ledger = DbLedger::open(ledger_path)?;
|
||||||
|
let entries = crate::entry::create_ticks(1, genesis_block.last_id());
|
||||||
|
db_ledger.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)?;
|
||||||
|
|
||||||
|
Ok((1, entries[0].id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn genesis<'a, I>(ledger_path: &str, keypair: &Keypair, entries: I) -> Result<()>
|
pub fn genesis<'a, I>(ledger_path: &str, keypair: &Keypair, entries: I) -> Result<()>
|
||||||
|
@ -875,7 +880,7 @@ pub fn get_tmp_ledger_path(name: &str) -> String {
|
||||||
|
|
||||||
pub fn create_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> String {
|
pub fn create_tmp_ledger(name: &str, genesis_block: &GenesisBlock) -> String {
|
||||||
let ledger_path = get_tmp_ledger_path(name);
|
let ledger_path = get_tmp_ledger_path(name);
|
||||||
create_empty_ledger(&ledger_path, genesis_block).unwrap();
|
create_new_ledger(&ledger_path, genesis_block).unwrap();
|
||||||
ledger_path
|
ledger_path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -384,7 +384,9 @@ impl Fullnode {
|
||||||
let entries = db_ledger.read_ledger().expect("opening ledger");
|
let entries = db_ledger.read_ledger().expect("opening ledger");
|
||||||
info!("processing ledger...");
|
info!("processing ledger...");
|
||||||
|
|
||||||
let (entry_height, last_entry_id) = bank.process_ledger(entries).expect("process_ledger");
|
let (entry_height, last_entry_id) = bank
|
||||||
|
.process_ledger(genesis_block, entries)
|
||||||
|
.expect("process_ledger");
|
||||||
// entry_height is the network-wide agreed height of the ledger.
|
// entry_height is the network-wide agreed height of the ledger.
|
||||||
// initialize it from the input ledger
|
// initialize it from the input ledger
|
||||||
info!(
|
info!(
|
||||||
|
|
|
@ -347,7 +347,6 @@ mod test {
|
||||||
let initial_tick_height = genesis_entry_height;
|
let initial_tick_height = genesis_entry_height;
|
||||||
let active_set_entries_len = active_set_entries.len() as u64;
|
let active_set_entries_len = active_set_entries.len() as u64;
|
||||||
let initial_non_tick_height = genesis_entry_height - initial_tick_height;
|
let initial_non_tick_height = genesis_entry_height - initial_tick_height;
|
||||||
let initial_entry_len = genesis_entry_height + active_set_entries_len;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let db_ledger = DbLedger::open(&my_ledger_path).unwrap();
|
let db_ledger = DbLedger::open(&my_ledger_path).unwrap();
|
||||||
|
@ -361,10 +360,10 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the LeaderScheduler so that this node becomes the leader at
|
// Set up the LeaderScheduler so that this node becomes the leader at
|
||||||
// bootstrap_height = num_bootstrap_slots * leader_rotation_interval
|
// bootstrap_height
|
||||||
let leader_rotation_interval = 16;
|
let leader_rotation_interval = 16;
|
||||||
let num_bootstrap_slots = 2;
|
let bootstrap_height = 2 * leader_rotation_interval;
|
||||||
let bootstrap_height = num_bootstrap_slots * leader_rotation_interval;
|
assert!((num_ending_ticks as u64) < bootstrap_height);
|
||||||
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
let leader_scheduler_config = LeaderSchedulerConfig::new(
|
||||||
bootstrap_height,
|
bootstrap_height,
|
||||||
leader_rotation_interval,
|
leader_rotation_interval,
|
||||||
|
@ -376,7 +375,7 @@ mod test {
|
||||||
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config)));
|
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config)));
|
||||||
|
|
||||||
// Set up the bank
|
// Set up the bank
|
||||||
let (bank, _, last_entry_id) =
|
let (bank, entry_height, last_entry_id) =
|
||||||
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
||||||
|
|
||||||
// Set up the replay stage
|
// Set up the replay stage
|
||||||
|
@ -390,31 +389,27 @@ mod test {
|
||||||
Arc::new(RwLock::new(cluster_info_me)),
|
Arc::new(RwLock::new(cluster_info_me)),
|
||||||
entry_receiver,
|
entry_receiver,
|
||||||
exit.clone(),
|
exit.clone(),
|
||||||
Arc::new(RwLock::new(initial_entry_len)),
|
Arc::new(RwLock::new(entry_height)),
|
||||||
Arc::new(RwLock::new(last_entry_id)),
|
Arc::new(RwLock::new(last_entry_id)),
|
||||||
rotation_sender,
|
rotation_sender,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send enough ticks to trigger leader rotation
|
// Send enough ticks to trigger leader rotation
|
||||||
let extra_entries = leader_rotation_interval;
|
let total_entries_to_send = (bootstrap_height + leader_rotation_interval) as usize;
|
||||||
let total_entries_to_send = (bootstrap_height + extra_entries) as usize;
|
|
||||||
let num_hashes = 1;
|
|
||||||
let mut entries_to_send = vec![];
|
let mut entries_to_send = vec![];
|
||||||
while entries_to_send.len() < total_entries_to_send {
|
while entries_to_send.len() < total_entries_to_send {
|
||||||
let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]);
|
let entry = Entry::new(&mut last_id, 0, 1, vec![]);
|
||||||
last_id = entry.id;
|
last_id = entry.id;
|
||||||
entries_to_send.push(entry);
|
entries_to_send.push(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!((num_ending_ticks as u64) < bootstrap_height);
|
|
||||||
|
|
||||||
// Add on the only entries that weren't ticks to the bootstrap height to get the
|
// Add on the only entries that weren't ticks to the bootstrap height to get the
|
||||||
// total expected entry length
|
// total expected entry length
|
||||||
let leader_rotation_index = (bootstrap_height - initial_tick_height) as usize;
|
let leader_rotation_index = (bootstrap_height - initial_tick_height) as usize;
|
||||||
let expected_entry_height =
|
let expected_entry_height =
|
||||||
bootstrap_height + initial_non_tick_height + active_set_entries_len - 1;
|
bootstrap_height + initial_non_tick_height + active_set_entries_len;
|
||||||
let expected_last_id = entries_to_send[leader_rotation_index - 2].id;
|
let expected_last_id = entries_to_send[leader_rotation_index - 1].id;
|
||||||
entry_sender.send(entries_to_send.clone()).unwrap();
|
entry_sender.send(entries_to_send.clone()).unwrap();
|
||||||
|
|
||||||
// Wait for replay_stage to exit and check return value is correct
|
// Wait for replay_stage to exit and check return value is correct
|
||||||
|
@ -440,7 +435,7 @@ mod test {
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&received_ticks[..],
|
&received_ticks[..],
|
||||||
&entries_to_send[..leader_rotation_index - 1]
|
&entries_to_send[..leader_rotation_index]
|
||||||
);
|
);
|
||||||
//replay stage should continue running even after rotation has happened (tvu never goes down)
|
//replay stage should continue running even after rotation has happened (tvu never goes down)
|
||||||
assert_eq!(exit.load(Ordering::Relaxed), false);
|
assert_eq!(exit.load(Ordering::Relaxed), false);
|
||||||
|
@ -470,7 +465,7 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set up the bank
|
// Set up the bank
|
||||||
let (bank, entry_height, last_id) =
|
let (bank, entry_height, last_entry_id) =
|
||||||
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
||||||
|
|
||||||
// Set up the cluster info
|
// Set up the cluster info
|
||||||
|
@ -491,7 +486,7 @@ mod test {
|
||||||
entry_receiver,
|
entry_receiver,
|
||||||
exit.clone(),
|
exit.clone(),
|
||||||
Arc::new(RwLock::new(entry_height)),
|
Arc::new(RwLock::new(entry_height)),
|
||||||
Arc::new(RwLock::new(last_id)),
|
Arc::new(RwLock::new(last_entry_id)),
|
||||||
to_leader_sender,
|
to_leader_sender,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -503,7 +498,7 @@ mod test {
|
||||||
vote_signer_proxy.send_validator_vote(&bank, &cluster_info_me, &mock_sender);
|
vote_signer_proxy.send_validator_vote(&bank, &cluster_info_me, &mock_sender);
|
||||||
|
|
||||||
// Send ReplayStage an entry, should see it on the ledger writer receiver
|
// Send ReplayStage an entry, should see it on the ledger writer receiver
|
||||||
let next_tick = create_ticks(1, last_id);
|
let next_tick = create_ticks(1, last_entry_id);
|
||||||
entry_sender
|
entry_sender
|
||||||
.send(next_tick.clone())
|
.send(next_tick.clone())
|
||||||
.expect("Error sending entry to ReplayStage");
|
.expect("Error sending entry to ReplayStage");
|
||||||
|
@ -521,6 +516,8 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vote_error_replay_stage_leader_rotation() {
|
fn test_vote_error_replay_stage_leader_rotation() {
|
||||||
|
solana_logger::setup();
|
||||||
|
|
||||||
// Set up dummy node to host a ReplayStage
|
// Set up dummy node to host a ReplayStage
|
||||||
let my_keypair = Keypair::new();
|
let my_keypair = Keypair::new();
|
||||||
let my_id = my_keypair.pubkey();
|
let my_id = my_keypair.pubkey();
|
||||||
|
@ -549,7 +546,6 @@ mod test {
|
||||||
let initial_tick_height = genesis_entry_height;
|
let initial_tick_height = genesis_entry_height;
|
||||||
let active_set_entries_len = active_set_entries.len() as u64;
|
let active_set_entries_len = active_set_entries.len() as u64;
|
||||||
let initial_non_tick_height = genesis_entry_height - initial_tick_height;
|
let initial_non_tick_height = genesis_entry_height - initial_tick_height;
|
||||||
let initial_entry_len = genesis_entry_height + active_set_entries_len;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let db_ledger = DbLedger::open(&my_ledger_path).unwrap();
|
let db_ledger = DbLedger::open(&my_ledger_path).unwrap();
|
||||||
|
@ -578,7 +574,7 @@ mod test {
|
||||||
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config)));
|
Arc::new(RwLock::new(LeaderScheduler::new(&leader_scheduler_config)));
|
||||||
|
|
||||||
// Set up the bank
|
// Set up the bank
|
||||||
let (bank, _, last_entry_id) =
|
let (bank, entry_height, last_entry_id) =
|
||||||
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
Fullnode::new_bank_from_ledger(&my_ledger_path, leader_scheduler);
|
||||||
|
|
||||||
// Set up the cluster info
|
// Set up the cluster info
|
||||||
|
@ -597,7 +593,7 @@ mod test {
|
||||||
cluster_info_me.clone(),
|
cluster_info_me.clone(),
|
||||||
entry_receiver,
|
entry_receiver,
|
||||||
exit.clone(),
|
exit.clone(),
|
||||||
Arc::new(RwLock::new(initial_entry_len as u64)),
|
Arc::new(RwLock::new(entry_height)),
|
||||||
Arc::new(RwLock::new(last_entry_id)),
|
Arc::new(RwLock::new(last_entry_id)),
|
||||||
rotation_tx,
|
rotation_tx,
|
||||||
None,
|
None,
|
||||||
|
@ -611,16 +607,15 @@ mod test {
|
||||||
|
|
||||||
// Send enough ticks to trigger leader rotation
|
// Send enough ticks to trigger leader rotation
|
||||||
let total_entries_to_send = (bootstrap_height - initial_tick_height) as usize;
|
let total_entries_to_send = (bootstrap_height - initial_tick_height) as usize;
|
||||||
let num_hashes = 1;
|
|
||||||
|
|
||||||
// Add on the only entries that weren't ticks to the bootstrap height to get the
|
// Add on the only entries that weren't ticks to the bootstrap height to get the
|
||||||
// total expected entry length
|
// total expected entry length
|
||||||
let expected_entry_height =
|
let expected_entry_height =
|
||||||
bootstrap_height + initial_non_tick_height + active_set_entries_len - 1;
|
bootstrap_height + initial_non_tick_height + active_set_entries_len;
|
||||||
let leader_rotation_index = (bootstrap_height - initial_tick_height - 2) as usize;
|
let leader_rotation_index = (bootstrap_height - initial_tick_height - 1) as usize;
|
||||||
let mut expected_last_id = Hash::default();
|
let mut expected_last_id = Hash::default();
|
||||||
for i in 0..total_entries_to_send - 1 {
|
for i in 0..total_entries_to_send {
|
||||||
let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]);
|
let entry = Entry::new(&mut last_id, 0, 1, vec![]);
|
||||||
last_id = entry.id;
|
last_id = entry.id;
|
||||||
entry_sender
|
entry_sender
|
||||||
.send(vec![entry.clone()])
|
.send(vec![entry.clone()])
|
||||||
|
@ -640,7 +635,7 @@ mod test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for replay_stage to exit and check return value is correct
|
info!("Wait for replay_stage to exit and check return value is correct");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Some(TvuReturnType::LeaderRotation(
|
Some(TvuReturnType::LeaderRotation(
|
||||||
bootstrap_height,
|
bootstrap_height,
|
||||||
|
@ -656,7 +651,8 @@ mod test {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_ne!(expected_last_id, Hash::default());
|
assert_ne!(expected_last_id, Hash::default());
|
||||||
//replay stage should continue running even after rotation has happened (tvu never goes down)
|
|
||||||
|
info!("Replay stage should continue running even after rotation has happened (TVU never goes down)");
|
||||||
assert_eq!(exit.load(Ordering::Relaxed), false);
|
assert_eq!(exit.load(Ordering::Relaxed), false);
|
||||||
let _ignored = remove_dir_all(&my_ledger_path);
|
let _ignored = remove_dir_all(&my_ledger_path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
|
||||||
let bob_pubkey = Keypair::new().pubkey();
|
let bob_pubkey = Keypair::new().pubkey();
|
||||||
let mut ledger_paths = Vec::new();
|
let mut ledger_paths = Vec::new();
|
||||||
|
|
||||||
let (alice, leader_ledger_path, _last_entry_height, _last_entry_id) =
|
let (alice, leader_ledger_path, last_entry_height, last_entry_id) =
|
||||||
create_tmp_sample_ledger("multi_node_ledger_window", 10_000, 0, leader_data.id, 500);
|
create_tmp_sample_ledger("multi_node_ledger_window", 10_000, 0, leader_data.id, 500);
|
||||||
ledger_paths.push(leader_ledger_path.clone());
|
ledger_paths.push(leader_ledger_path.clone());
|
||||||
|
|
||||||
|
@ -146,10 +146,10 @@ fn test_multi_node_ledger_window() -> result::Result<()> {
|
||||||
// write a bunch more ledger into leader's ledger, this should populate the leader's window
|
// write a bunch more ledger into leader's ledger, this should populate the leader's window
|
||||||
// and force it to respond to repair from the ledger window
|
// and force it to respond to repair from the ledger window
|
||||||
{
|
{
|
||||||
let entries = make_tiny_test_entries(genesis_block.last_id(), 100);
|
let entries = make_tiny_test_entries(last_entry_id, 100);
|
||||||
let db_ledger = DbLedger::open(&leader_ledger_path).unwrap();
|
let db_ledger = DbLedger::open(&leader_ledger_path).unwrap();
|
||||||
db_ledger
|
db_ledger
|
||||||
.write_entries(DEFAULT_SLOT_HEIGHT, 0, &entries)
|
.write_entries(DEFAULT_SLOT_HEIGHT, last_entry_height, &entries)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue