add tick_height to Entry to be able to repair by period, chain forks of Entries, etc. (#2096)
This commit is contained in:
parent
b51bcb55db
commit
aeee25e703
16
src/bank.rs
16
src/bank.rs
|
@ -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]),
|
||||||
|
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
|
61
src/entry.rs
61
src/entry.rs
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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![],
|
||||||
|
|
|
@ -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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
10
src/tvu.rs
10
src/tvu.rs
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue