add tick_height to Entry to be able to repair by period, chain forks of Entries, etc. (#2096)

This commit is contained in:
Rob Walker 2018-12-10 20:03:04 -08:00 committed by GitHub
parent b51bcb55db
commit aeee25e703
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 95 additions and 58 deletions

View File

@ -1821,7 +1821,7 @@ mod tests {
let mut e = ledger::next_entries(&hash, 0, txs); let mut e = ledger::next_entries(&hash, 0, txs);
entries.append(&mut e); entries.append(&mut e);
hash = entries.last().unwrap().id; hash = entries.last().unwrap().id;
let tick = Entry::new(&hash, num_hashes, vec![]); let tick = Entry::new(&hash, 0, num_hashes, vec![]);
hash = tick.id; hash = tick.id;
last_id = hash; last_id = hash;
entries.push(tick); entries.push(tick);
@ -1842,11 +1842,11 @@ mod tests {
for i in 0..length { for i in 0..length {
let keypair = Keypair::new(); let keypair = Keypair::new();
let tx = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 1, last_id); let tx = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 1, last_id);
let entry = Entry::new(&hash, num_hashes, vec![tx]); let entry = Entry::new(&hash, 0, num_hashes, vec![tx]);
hash = entry.id; hash = entry.id;
entries.push(entry); entries.push(entry);
if (i + 1) % ticks == 0 { if (i + 1) % ticks == 0 {
let tick = Entry::new(&hash, num_hashes, vec![]); let tick = Entry::new(&hash, 0, num_hashes, vec![]);
hash = tick.id; hash = tick.id;
last_id = hash; last_id = hash;
entries.push(tick); entries.push(tick);
@ -2154,16 +2154,16 @@ mod tests {
// ensure bank can process 2 entries that do not have a common account and tick is registered // ensure bank can process 2 entries that do not have a common account and tick is registered
let tx = Transaction::system_new(&keypair2, keypair3.pubkey(), 1, bank.last_id()); let tx = Transaction::system_new(&keypair2, keypair3.pubkey(), 1, bank.last_id());
let entry_1 = next_entry(&last_id, 1, vec![tx]); let entry_1 = next_entry(&last_id, 1, vec![tx]);
let new_tick = next_entry(&entry_1.id, 1, vec![]); let tick = next_entry(&entry_1.id, 1, vec![]);
let tx = Transaction::system_new(&keypair1, keypair4.pubkey(), 1, new_tick.id); let tx = Transaction::system_new(&keypair1, keypair4.pubkey(), 1, tick.id);
let entry_2 = next_entry(&new_tick.id, 1, vec![tx]); let entry_2 = next_entry(&tick.id, 1, vec![tx]);
assert_eq!( assert_eq!(
bank.par_process_entries(&[entry_1.clone(), new_tick.clone(), entry_2]), bank.par_process_entries(&[entry_1.clone(), tick.clone(), entry_2]),
Ok(()) Ok(())
); );
assert_eq!(bank.get_balance(&keypair3.pubkey()), 1); assert_eq!(bank.get_balance(&keypair3.pubkey()), 1);
assert_eq!(bank.get_balance(&keypair4.pubkey()), 1); assert_eq!(bank.get_balance(&keypair4.pubkey()), 1);
assert_eq!(bank.last_id(), new_tick.id); assert_eq!(bank.last_id(), tick.id);
// ensure that errors are returned // ensure that errors are returned
assert_eq!( assert_eq!(
bank.par_process_entries(&[entry_1]), bank.par_process_entries(&[entry_1]),

View File

@ -1292,8 +1292,8 @@ mod tests {
writer writer
.write_entries( .write_entries(
&vec![ &vec![
Entry::new_tick(&zero, 0, &zero), Entry::new_tick(&zero, 0, 0, &zero),
Entry::new_tick(&one, 0, &one), Entry::new_tick(&one, 1, 0, &one),
] ]
.to_vec(), .to_vec(),
) )

View File

@ -37,6 +37,9 @@ pub struct Entry {
/// The the previous Entry ID. /// The the previous Entry ID.
pub prev_id: Hash, pub prev_id: Hash,
/// tick height of the ledger, not including any tick implied by this Entry
pub tick_height: u64,
/// The number of hashes since the previous Entry ID. /// The number of hashes since the previous Entry ID.
pub num_hashes: u64, pub num_hashes: u64,
@ -51,11 +54,17 @@ pub struct Entry {
impl Entry { impl Entry {
/// Creates the next Entry `num_hashes` after `start_hash`. /// Creates the next Entry `num_hashes` after `start_hash`.
pub fn new(prev_id: &Hash, num_hashes: u64, transactions: Vec<Transaction>) -> Self { pub fn new(
prev_id: &Hash,
tick_height: u64,
num_hashes: u64,
transactions: Vec<Transaction>,
) -> Self {
let entry = { let entry = {
if num_hashes == 0 && transactions.is_empty() { if num_hashes == 0 && transactions.is_empty() {
Entry { Entry {
prev_id: *prev_id, prev_id: *prev_id,
tick_height,
num_hashes: 0, num_hashes: 0,
id: *prev_id, id: *prev_id,
transactions, transactions,
@ -66,6 +75,7 @@ impl Entry {
let id = next_hash(prev_id, 1, &transactions); let id = next_hash(prev_id, 1, &transactions);
Entry { Entry {
prev_id: *prev_id, prev_id: *prev_id,
tick_height,
num_hashes: 1, num_hashes: 1,
id, id,
transactions, transactions,
@ -77,6 +87,7 @@ impl Entry {
let id = next_hash(prev_id, num_hashes, &transactions); let id = next_hash(prev_id, num_hashes, &transactions);
Entry { Entry {
prev_id: *prev_id, prev_id: *prev_id,
tick_height,
num_hashes, num_hashes,
id, id,
transactions, transactions,
@ -129,9 +140,9 @@ impl Entry {
pub fn serialized_size(transactions: &[Transaction]) -> u64 { pub fn serialized_size(transactions: &[Transaction]) -> u64 {
let txs_size = serialized_size(transactions).unwrap(); let txs_size = serialized_size(transactions).unwrap();
// num_hashes + id + prev_id + txs // tick_height+num_hashes + id+prev_id + txs
(size_of::<u64>() + 2 * size_of::<Hash>()) as u64 + txs_size (2 * size_of::<u64>() + 2 * size_of::<Hash>()) as u64 + txs_size
} }
pub fn num_will_fit(transactions: &[Transaction]) -> usize { pub fn num_will_fit(transactions: &[Transaction]) -> usize {
@ -176,18 +187,22 @@ impl Entry {
num_hashes: &mut u64, num_hashes: &mut u64,
transactions: Vec<Transaction>, transactions: Vec<Transaction>,
) -> Self { ) -> Self {
let entry = Self::new(start_hash, *num_hashes, transactions); let entry = Self::new(start_hash, 0, *num_hashes, transactions);
*start_hash = entry.id; *start_hash = entry.id;
*num_hashes = 0; *num_hashes = 0;
assert!(serialized_size(&entry).unwrap() <= BLOB_DATA_SIZE as u64); assert!(serialized_size(&entry).unwrap() <= BLOB_DATA_SIZE as u64);
entry entry
} }
/// Creates a Entry from the number of hashes `num_hashes` since the previous transaction /// Creates a Entry from the number of hashes `num_hashes`
/// and that resulting `id`. /// since the previous transaction and that resulting `id`.
pub fn new_tick(prev_id: &Hash, num_hashes: u64, id: &Hash) -> Self {
#[cfg(test)]
pub fn new_tick(prev_id: &Hash, tick_height: u64, num_hashes: u64, id: &Hash) -> Self {
Entry { Entry {
prev_id: *prev_id, prev_id: *prev_id,
tick_height,
num_hashes, num_hashes,
id: *id, id: *id,
transactions: vec![], transactions: vec![],
@ -239,17 +254,6 @@ fn next_hash(start_hash: &Hash, num_hashes: u64, transactions: &[Transaction]) -
} }
} }
/// Creates the next Tick or Transaction Entry `num_hashes` after `start_hash`.
pub fn next_entry(prev_id: &Hash, num_hashes: u64, transactions: Vec<Transaction>) -> Entry {
assert!(num_hashes > 0 || transactions.is_empty());
Entry {
prev_id: *prev_id,
num_hashes,
id: next_hash(prev_id, num_hashes, &transactions),
transactions,
}
}
pub fn reconstruct_entries_from_blobs(blobs: Vec<SharedBlob>) -> Result<(Vec<Entry>, u64)> { pub fn reconstruct_entries_from_blobs(blobs: Vec<SharedBlob>) -> Result<(Vec<Entry>, u64)> {
let mut entries: Vec<Entry> = Vec::with_capacity(blobs.len()); let mut entries: Vec<Entry> = Vec::with_capacity(blobs.len());
let mut num_ticks = 0; let mut num_ticks = 0;
@ -269,6 +273,19 @@ pub fn reconstruct_entries_from_blobs(blobs: Vec<SharedBlob>) -> Result<(Vec<Ent
Ok((entries, num_ticks)) Ok((entries, num_ticks))
} }
#[cfg(test)]
/// Creates the next Tick or Transaction Entry `num_hashes` after `start_hash`.
pub fn next_entry(prev_id: &Hash, num_hashes: u64, transactions: Vec<Transaction>) -> Entry {
assert!(num_hashes > 0 || transactions.is_empty());
Entry {
prev_id: *prev_id,
tick_height: 0,
num_hashes,
id: next_hash(prev_id, num_hashes, &transactions),
transactions,
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -284,8 +301,8 @@ mod tests {
fn test_entry_verify() { fn test_entry_verify() {
let zero = Hash::default(); let zero = Hash::default();
let one = hash(&zero.as_ref()); let one = hash(&zero.as_ref());
assert!(Entry::new_tick(&zero, 0, &zero).verify(&zero)); // base case, never used assert!(Entry::new_tick(&zero, 0, 0, &zero).verify(&zero)); // base case, never used
assert!(!Entry::new_tick(&zero, 0, &zero).verify(&one)); // base case, bad assert!(!Entry::new_tick(&zero, 1, 0, &zero).verify(&one)); // base case, bad
assert!(next_entry(&zero, 1, vec![]).verify(&zero)); // inductive step assert!(next_entry(&zero, 1, vec![]).verify(&zero)); // inductive step
assert!(next_entry(&zero, 1, vec![]).verify_self()); // also inductive step assert!(next_entry(&zero, 1, vec![]).verify_self()); // also inductive step
assert!(!next_entry(&zero, 1, vec![]).verify(&one)); // inductive step, bad assert!(!next_entry(&zero, 1, vec![]).verify(&one)); // inductive step, bad
@ -299,7 +316,7 @@ mod tests {
let keypair = Keypair::new(); let keypair = Keypair::new();
let tx0 = Transaction::system_new(&keypair, keypair.pubkey(), 0, zero); let tx0 = Transaction::system_new(&keypair, keypair.pubkey(), 0, zero);
let tx1 = Transaction::system_new(&keypair, keypair.pubkey(), 1, zero); let tx1 = Transaction::system_new(&keypair, keypair.pubkey(), 1, zero);
let mut e0 = Entry::new(&zero, 0, vec![tx0.clone(), tx1.clone()]); let mut e0 = Entry::new(&zero, 0, 0, vec![tx0.clone(), tx1.clone()]);
assert!(e0.verify(&zero)); assert!(e0.verify(&zero));
// Next, swap two transactions and ensure verification fails. // Next, swap two transactions and ensure verification fails.
@ -323,7 +340,7 @@ mod tests {
); );
let tx1 = let tx1 =
Transaction::budget_new_signature(&keypair, keypair.pubkey(), keypair.pubkey(), zero); Transaction::budget_new_signature(&keypair, keypair.pubkey(), keypair.pubkey(), zero);
let mut e0 = Entry::new(&zero, 0, vec![tx0.clone(), tx1.clone()]); let mut e0 = Entry::new(&zero, 0, 0, vec![tx0.clone(), tx1.clone()]);
assert!(e0.verify(&zero)); assert!(e0.verify(&zero));
// Next, swap two witness transactions and ensure verification fails. // Next, swap two witness transactions and ensure verification fails.

View File

@ -483,20 +483,20 @@ pub fn make_active_set_entries(
// 1) Create transfer token entry // 1) Create transfer token entry
let transfer_tx = let transfer_tx =
Transaction::system_new(&token_source, active_keypair.pubkey(), 3, *last_tick_id); Transaction::system_new(&token_source, active_keypair.pubkey(), 3, *last_tick_id);
let transfer_entry = Entry::new(last_entry_id, 1, vec![transfer_tx]); let transfer_entry = Entry::new(last_entry_id, 0, 1, vec![transfer_tx]);
let mut last_entry_id = transfer_entry.id; let mut last_entry_id = transfer_entry.id;
// 2) Create and register the vote account // 2) Create and register the vote account
let vote_account = Keypair::new(); let vote_account = Keypair::new();
let new_vote_account_tx = let new_vote_account_tx =
Transaction::vote_account_new(active_keypair, vote_account.pubkey(), *last_tick_id, 1, 1); Transaction::vote_account_new(active_keypair, vote_account.pubkey(), *last_tick_id, 1, 1);
let new_vote_account_entry = Entry::new(&last_entry_id, 1, vec![new_vote_account_tx]); let new_vote_account_entry = Entry::new(&last_entry_id, 0, 1, vec![new_vote_account_tx]);
last_entry_id = new_vote_account_entry.id; last_entry_id = new_vote_account_entry.id;
// 3) Create vote entry // 3) Create vote entry
let vote = Vote { tick_height: 1 }; let vote = Vote { tick_height: 1 };
let vote_tx = Transaction::vote_new(&vote_account, vote, *last_tick_id, 0); let vote_tx = Transaction::vote_new(&vote_account, vote, *last_tick_id, 0);
let vote_entry = Entry::new(&last_entry_id, 1, vec![vote_tx]); let vote_entry = Entry::new(&last_entry_id, 0, 1, vec![vote_tx]);
last_entry_id = vote_entry.id; last_entry_id = vote_entry.id;
// 4) Create the ending empty ticks // 4) Create the ending empty ticks

View File

@ -458,7 +458,13 @@ pub trait Block {
impl Block for [Entry] { impl Block for [Entry] {
fn verify(&self, start_hash: &Hash) -> bool { fn verify(&self, start_hash: &Hash) -> bool {
let genesis = [Entry::new_tick(start_hash, 0, start_hash)]; let genesis = [Entry {
prev_id: *start_hash,
tick_height: 0,
num_hashes: 0,
id: *start_hash,
transactions: vec![],
}];
let entry_pairs = genesis.par_iter().chain(self).zip(self); let entry_pairs = genesis.par_iter().chain(self).zip(self);
entry_pairs.all(|(x0, x1)| { entry_pairs.all(|(x0, x1)| {
let r = x1.verify(&x0.id); let r = x1.verify(&x0.id);
@ -609,8 +615,8 @@ pub fn create_tmp_genesis(
pub fn create_ticks(num_ticks: usize, mut hash: Hash) -> Vec<Entry> { pub fn create_ticks(num_ticks: usize, mut hash: Hash) -> Vec<Entry> {
let mut ticks = Vec::with_capacity(num_ticks as usize); let mut ticks = Vec::with_capacity(num_ticks as usize);
for _ in 0..num_ticks { for _ in 0..num_ticks as u64 {
let new_tick = Entry::new(&hash, 1, vec![]); let new_tick = Entry::new(&hash, 0, 1, vec![]);
hash = new_tick.id; hash = new_tick.id;
ticks.push(new_tick); ticks.push(new_tick);
} }
@ -719,8 +725,8 @@ mod tests {
let zero = Hash::default(); let zero = Hash::default();
let one = hash(&zero.as_ref()); let one = hash(&zero.as_ref());
assert!(vec![][..].verify(&zero)); // base case assert!(vec![][..].verify(&zero)); // base case
assert!(vec![Entry::new_tick(&zero, 0, &zero)][..].verify(&zero)); // singleton case 1 assert!(vec![Entry::new_tick(&zero, 0, 0, &zero)][..].verify(&zero)); // singleton case 1
assert!(!vec![Entry::new_tick(&zero, 0, &zero)][..].verify(&one)); // singleton case 2, bad assert!(!vec![Entry::new_tick(&zero, 0, 0, &zero)][..].verify(&one)); // singleton case 2, bad
assert!(vec![next_entry(&zero, 0, vec![]); 2][..].verify(&zero)); // inductive step assert!(vec![next_entry(&zero, 0, vec![]); 2][..].verify(&zero)); // inductive step
let mut bad_ticks = vec![next_entry(&zero, 0, vec![]); 2]; let mut bad_ticks = vec![next_entry(&zero, 0, vec![]); 2];
@ -791,6 +797,7 @@ mod tests {
let tx_large_size = serialized_size(&tx_large).unwrap() as usize; let tx_large_size = serialized_size(&tx_large).unwrap() as usize;
let entry_size = serialized_size(&Entry { let entry_size = serialized_size(&Entry {
prev_id: Hash::default(), prev_id: Hash::default(),
tick_height: 0,
num_hashes: 0, num_hashes: 0,
id: Hash::default(), id: Hash::default(),
transactions: vec![], transactions: vec![],

View File

@ -96,9 +96,9 @@ impl Mint {
} }
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, 0, vec![]);
let e1 = Entry::new(&e0.id, 1, self.create_transaction()); let e1 = Entry::new(&e0.id, 0, 1, self.create_transaction());
let e2 = Entry::new(&e1.id, 1, vec![]); // include a tick let e2 = Entry::new(&e1.id, 0, 1, vec![]); // include a tick
vec![e0, e1, e2] vec![e0, e1, e2]
} }
} }

View File

@ -462,7 +462,7 @@ pub fn make_consecutive_blobs(
let num_hashes = 1; let num_hashes = 1;
let mut all_entries = Vec::with_capacity(num_blobs_to_make as usize); let mut all_entries = Vec::with_capacity(num_blobs_to_make as usize);
for _ in 0..num_blobs_to_make { for _ in 0..num_blobs_to_make {
let entry = Entry::new(&last_hash, num_hashes, vec![]); let entry = Entry::new(&last_hash, 0, num_hashes, vec![]);
last_hash = entry.id; last_hash = entry.id;
all_entries.push(entry); all_entries.push(entry);
} }

View File

@ -12,6 +12,7 @@ pub struct Poh {
#[derive(Debug)] #[derive(Debug)]
pub struct PohEntry { pub struct PohEntry {
pub prev_id: Hash, pub prev_id: Hash,
pub tick_height: u64,
pub num_hashes: u64, pub num_hashes: u64,
pub id: Hash, pub id: Hash,
pub mixin: Option<Hash>, pub mixin: Option<Hash>,
@ -43,6 +44,7 @@ impl Poh {
PohEntry { PohEntry {
prev_id, prev_id,
tick_height: self.tick_height,
num_hashes, num_hashes,
id: self.id, id: self.id,
mixin: Some(mixin), mixin: Some(mixin),
@ -60,10 +62,12 @@ impl Poh {
let prev_id = self.prev_id; let prev_id = self.prev_id;
self.prev_id = self.id; self.prev_id = self.id;
let tick_height = self.tick_height;
self.tick_height += 1; self.tick_height += 1;
PohEntry { PohEntry {
prev_id, prev_id,
tick_height,
num_hashes, num_hashes,
id: self.id, id: self.id,
mixin: None, mixin: None,
@ -106,6 +110,7 @@ mod tests {
Hash::default(), Hash::default(),
&[PohEntry { &[PohEntry {
prev_id: Hash::default(), prev_id: Hash::default(),
tick_height: 0,
num_hashes: 0, num_hashes: 0,
id: Hash::default(), id: Hash::default(),
mixin: None, mixin: None,

View File

@ -93,6 +93,7 @@ impl PohRecorder {
assert!(!txs.is_empty(), "Entries without transactions are used to track real-time passing in the ledger and can only be generated with PohRecorder::tick function"); assert!(!txs.is_empty(), "Entries without transactions are used to track real-time passing in the ledger and can only be generated with PohRecorder::tick function");
let entry = Entry { let entry = Entry {
prev_id: entry.prev_id, prev_id: entry.prev_id,
tick_height: entry.tick_height,
num_hashes: entry.num_hashes, num_hashes: entry.num_hashes,
id: entry.id, id: entry.id,
transactions: txs, transactions: txs,
@ -105,6 +106,7 @@ impl PohRecorder {
let tick = poh.tick(); let tick = poh.tick();
let tick = Entry { let tick = Entry {
prev_id: tick.prev_id, prev_id: tick.prev_id,
tick_height: tick.tick_height,
num_hashes: tick.num_hashes, num_hashes: tick.num_hashes,
id: tick.id, id: tick.id,
transactions: vec![], transactions: vec![],
@ -136,11 +138,17 @@ mod tests {
let h1 = hash(b"hello world!"); let h1 = hash(b"hello world!");
let tx = test_tx(); let tx = test_tx();
assert!(poh_recorder.record(h1, vec![tx]).is_ok()); assert!(poh_recorder.record(h1, vec![tx]).is_ok());
assert!(poh_recorder.tick().is_ok());
//get some events //get some events
let _ = entry_receiver.recv().unwrap(); let e = entry_receiver.recv().unwrap();
let _ = entry_receiver.recv().unwrap(); assert_eq!(e[0].tick_height, 1);
assert!(poh_recorder.tick().is_ok());
let e = entry_receiver.recv().unwrap();
assert_eq!(e[0].tick_height, 1);
assert!(poh_recorder.tick().is_ok());
let e = entry_receiver.recv().unwrap();
assert_eq!(e[0].tick_height, 2);
//make sure it handles channel close correctly //make sure it handles channel close correctly
drop(entry_receiver); drop(entry_receiver);

View File

@ -348,7 +348,7 @@ mod test {
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, num_hashes, vec![]); let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]);
last_id = entry.id; last_id = entry.id;
entries_to_send.push(entry); entries_to_send.push(entry);
} }
@ -567,7 +567,7 @@ mod test {
let leader_rotation_index = (bootstrap_height - initial_tick_height - 1) 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 { for i in 0..total_entries_to_send {
let entry = Entry::new(&mut last_id, num_hashes, vec![]); let entry = Entry::new(&mut last_id, 0, num_hashes, vec![]);
last_id = entry.id; last_id = entry.id;
entry_sender entry_sender
.send(vec![entry.clone()]) .send(vec![entry.clone()])
@ -626,7 +626,7 @@ mod test {
let mut last_id = Hash::default(); let mut last_id = Hash::default();
let mut entries = Vec::new(); let mut entries = Vec::new();
for _ in 0..5 { for _ in 0..5 {
let entry = Entry::new(&mut last_id, 1, vec![]); //just ticks let entry = Entry::new(&mut last_id, 0, 1, vec![]); //just ticks
last_id = entry.id; last_id = entry.id;
entries.push(entry); entries.push(entry);
} }
@ -653,7 +653,7 @@ mod test {
entries.clear(); entries.clear();
for _ in 0..5 { for _ in 0..5 {
let entry = Entry::new(&mut Hash::default(), 0, vec![]); //just broken entries let entry = Entry::new(&mut Hash::default(), 0, 0, vec![]); //just broken entries
entries.push(entry); entries.push(entry);
} }
entry_sender entry_sender

View File

@ -419,7 +419,7 @@ mod tests {
let keypair = Keypair::new(); let keypair = Keypair::new();
let vote_tx = VoteTransaction::vote_new(&keypair, vote, Hash::default(), 1); let vote_tx = VoteTransaction::vote_new(&keypair, vote, Hash::default(), 1);
vote_txs.push(vote_tx); vote_txs.push(vote_tx);
let vote_entries = vec![Entry::new(&Hash::default(), 1, vote_txs)]; let vote_entries = vec![Entry::new(&Hash::default(), 0, 1, vote_txs)];
storage_entry_sender.send(vote_entries).unwrap(); storage_entry_sender.send(vote_entries).unwrap();
for _ in 0..5 { for _ in 0..5 {

View File

@ -290,10 +290,10 @@ pub mod tests {
let transfer_amount = 501; let transfer_amount = 501;
let bob_keypair = Keypair::new(); let bob_keypair = Keypair::new();
for i in 0..num_transfers { for i in 0..num_transfers {
let entry0 = Entry::new(&cur_hash, i, vec![]); let entry0 = Entry::new(&cur_hash, 0, i, vec![]);
cur_hash = entry0.id; cur_hash = entry0.id;
bank.register_tick(&cur_hash); bank.register_tick(&cur_hash);
let entry_tick0 = Entry::new(&cur_hash, i + 1, vec![]); let entry_tick0 = Entry::new(&cur_hash, 0, i + 1, vec![]);
cur_hash = entry_tick0.id; cur_hash = entry_tick0.id;
let tx0 = Transaction::system_new( let tx0 = Transaction::system_new(
@ -303,11 +303,11 @@ pub mod tests {
cur_hash, cur_hash,
); );
bank.register_tick(&cur_hash); bank.register_tick(&cur_hash);
let entry_tick1 = Entry::new(&cur_hash, i + 1, vec![]); let entry_tick1 = Entry::new(&cur_hash, 0, i + 1, vec![]);
cur_hash = entry_tick1.id; cur_hash = entry_tick1.id;
let entry1 = Entry::new(&cur_hash, i + num_transfers, vec![tx0]); let entry1 = Entry::new(&cur_hash, 0, i + num_transfers, vec![tx0]);
bank.register_tick(&entry1.id); bank.register_tick(&entry1.id);
let entry_tick2 = Entry::new(&entry1.id, i + 1, vec![]); let entry_tick2 = Entry::new(&entry1.id, 0, i + 1, vec![]);
cur_hash = entry_tick2.id; cur_hash = entry_tick2.id;
alice_ref_balance -= transfer_amount; alice_ref_balance -= transfer_amount;