Rename SlotMeta::is_trunk to SlotMeta::is_rooted

This commit is contained in:
Greg Fitzgerald 2019-02-28 09:53:57 -07:00
parent 271115a6be
commit 4704aa1f80
2 changed files with 28 additions and 28 deletions

View File

@ -51,16 +51,16 @@ slot index and blob index for an entry, and the value is the entry data. Note bl
* `next_slots` - A list of future slots this slot could chain to. Used when rebuilding * `next_slots` - A list of future slots this slot could chain to. Used when rebuilding
the ledger to find possible fork points. the ledger to find possible fork points.
* `last_index` - The index of the blob that is flagged as the last blob for this slot. This flag on a blob will be set by the leader for a slot when they are transmitting the last blob for a slot. * `last_index` - The index of the blob that is flagged as the last blob for this slot. This flag on a blob will be set by the leader for a slot when they are transmitting the last blob for a slot.
* `is_trunk` - True iff every block from 0...slot forms a full sequence without any holes. We can derive is_trunk for each slot with the following rules. Let slot(n) be the slot with index `n`, and slot(n).is_full() is true if the slot with index `n` has all the ticks expected for that slot. Let is_trunk(n) be the statement that "the slot(n).is_trunk is true". Then: * `is_rooted` - True iff every block from 0...slot forms a full sequence without any holes. We can derive is_rooted for each slot with the following rules. Let slot(n) be the slot with index `n`, and slot(n).is_full() is true if the slot with index `n` has all the ticks expected for that slot. Let is_rooted(n) be the statement that "the slot(n).is_rooted is true". Then:
is_trunk(0) is_rooted(0)
is_trunk(n+1) iff (is_trunk(n) and slot(n).is_full() is_rooted(n+1) iff (is_rooted(n) and slot(n).is_full()
3. Chaining - When a blob for a new slot `x` arrives, we check the number of blocks (`num_blocks`) for that new slot (this information is encoded in the blob). We then know that this new slot chains to slot `x - num_blocks`. 3. Chaining - When a blob for a new slot `x` arrives, we check the number of blocks (`num_blocks`) for that new slot (this information is encoded in the blob). We then know that this new slot chains to slot `x - num_blocks`.
4. Subscriptions - The Blocktree records a set of slots that have been "subscribed" to. This means entries that chain to these slots will be sent on the Blocktree channel for consumption by the ReplayStage. See the `Blocktree APIs` for details. 4. Subscriptions - The Blocktree records a set of slots that have been "subscribed" to. This means entries that chain to these slots will be sent on the Blocktree channel for consumption by the ReplayStage. See the `Blocktree APIs` for details.
5. Update notifications - The Blocktree notifies listeners when slot(n).is_trunk is flipped from false to true for any `n`. 5. Update notifications - The Blocktree notifies listeners when slot(n).is_rooted is flipped from false to true for any `n`.
### Blocktree APIs ### Blocktree APIs

View File

@ -137,7 +137,7 @@ pub struct SlotMeta {
pub next_slots: Vec<u64>, pub next_slots: Vec<u64>,
// True if every block from 0..slot, where slot is the slot index of this slot // True if every block from 0..slot, where slot is the slot index of this slot
// is full // is full
pub is_trunk: bool, pub is_rooted: bool,
} }
impl SlotMeta { impl SlotMeta {
@ -152,7 +152,7 @@ impl SlotMeta {
received: 0, received: 0,
parent_slot, parent_slot,
next_slots: vec![], next_slots: vec![],
is_trunk: slot_height == 0, is_rooted: slot_height == 0,
last_index: std::u64::MAX, last_index: std::u64::MAX,
} }
} }
@ -894,7 +894,7 @@ impl Blocktree {
// from block 0, which is true iff: // from block 0, which is true iff:
// 1) The block with index prev_block_index is itself part of the trunk of consecutive blocks // 1) The block with index prev_block_index is itself part of the trunk of consecutive blocks
// starting from block 0, // starting from block 0,
slot_meta.is_trunk && slot_meta.is_rooted &&
// AND either: // AND either:
// 1) The slot didn't exist in the database before, and now we have a consecutive // 1) The slot didn't exist in the database before, and now we have a consecutive
// block for that slot // block for that slot
@ -957,7 +957,7 @@ impl Blocktree {
// This is a newly inserted slot so: // This is a newly inserted slot so:
// 1) Chain to the previous slot, and also // 1) Chain to the previous slot, and also
// 2) Determine whether to set the is_trunk flag // 2) Determine whether to set the is_rooted flag
self.chain_new_slot_to_prev_slot( self.chain_new_slot_to_prev_slot(
&mut prev_slot.borrow_mut(), &mut prev_slot.borrow_mut(),
slot_height, slot_height,
@ -968,15 +968,15 @@ impl Blocktree {
} }
if self.is_newly_completed_slot(&RefCell::borrow(&*meta_copy), meta_backup) if self.is_newly_completed_slot(&RefCell::borrow(&*meta_copy), meta_backup)
&& RefCell::borrow(&*meta_copy).is_trunk && RefCell::borrow(&*meta_copy).is_rooted
{ {
// This is a newly inserted slot and slot.is_trunk is true, so go through // This is a newly inserted slot and slot.is_rooted is true, so go through
// and update all child slots with is_trunk if applicable // and update all child slots with is_rooted if applicable
let mut next_slots: Vec<(u64, Rc<RefCell<(SlotMeta)>>)> = let mut next_slots: Vec<(u64, Rc<RefCell<(SlotMeta)>>)> =
vec![(slot_height, meta_copy.clone())]; vec![(slot_height, meta_copy.clone())];
while !next_slots.is_empty() { while !next_slots.is_empty() {
let (_, current_slot) = next_slots.pop().unwrap(); let (_, current_slot) = next_slots.pop().unwrap();
current_slot.borrow_mut().is_trunk = true; current_slot.borrow_mut().is_rooted = true;
let current_slot = &RefCell::borrow(&*current_slot); let current_slot = &RefCell::borrow(&*current_slot);
if current_slot.is_full() { if current_slot.is_full() {
@ -1002,7 +1002,7 @@ impl Blocktree {
current_slot: &mut SlotMeta, current_slot: &mut SlotMeta,
) { ) {
prev_slot.next_slots.push(current_slot_height); prev_slot.next_slots.push(current_slot_height);
current_slot.is_trunk = prev_slot.is_trunk && prev_slot.is_full(); current_slot.is_rooted = prev_slot.is_rooted && prev_slot.is_full();
} }
fn is_newly_completed_slot( fn is_newly_completed_slot(
@ -1180,7 +1180,7 @@ impl Blocktree {
bootstrap_meta.consumed = last.index() + 1; bootstrap_meta.consumed = last.index() + 1;
bootstrap_meta.received = last.index() + 1; bootstrap_meta.received = last.index() + 1;
bootstrap_meta.is_trunk = true; bootstrap_meta.is_rooted = true;
let mut batch = WriteBatch::default(); let mut batch = WriteBatch::default();
batch.put_cf( batch.put_cf(
@ -1590,7 +1590,7 @@ pub mod tests {
assert_eq!(meta.parent_slot, 0); assert_eq!(meta.parent_slot, 0);
assert_eq!(meta.last_index, num_entries - 1); assert_eq!(meta.last_index, num_entries - 1);
assert!(meta.next_slots.is_empty()); assert!(meta.next_slots.is_empty());
assert!(meta.is_trunk); assert!(meta.is_rooted);
// Destroying database without closing it first is undefined behavior // Destroying database without closing it first is undefined behavior
drop(ledger); drop(ledger);
@ -1996,7 +1996,7 @@ pub mod tests {
let s1 = blocktree.meta(1).unwrap().unwrap(); let s1 = blocktree.meta(1).unwrap().unwrap();
assert!(s1.next_slots.is_empty()); assert!(s1.next_slots.is_empty());
// Slot 1 is not trunk because slot 0 hasn't been inserted yet // Slot 1 is not trunk because slot 0 hasn't been inserted yet
assert!(!s1.is_trunk); assert!(!s1.is_rooted);
assert_eq!(s1.parent_slot, 0); assert_eq!(s1.parent_slot, 0);
assert_eq!(s1.last_index, entries_per_slot - 1); assert_eq!(s1.last_index, entries_per_slot - 1);
@ -2007,7 +2007,7 @@ pub mod tests {
let s2 = blocktree.meta(2).unwrap().unwrap(); let s2 = blocktree.meta(2).unwrap().unwrap();
assert!(s2.next_slots.is_empty()); assert!(s2.next_slots.is_empty());
// Slot 2 is not trunk because slot 0 hasn't been inserted yet // Slot 2 is not trunk because slot 0 hasn't been inserted yet
assert!(!s2.is_trunk); assert!(!s2.is_rooted);
assert_eq!(s2.parent_slot, 1); assert_eq!(s2.parent_slot, 1);
assert_eq!(s2.last_index, entries_per_slot - 1); assert_eq!(s2.last_index, entries_per_slot - 1);
@ -2015,7 +2015,7 @@ pub mod tests {
// but still isn't part of the trunk // but still isn't part of the trunk
let s1 = blocktree.meta(1).unwrap().unwrap(); let s1 = blocktree.meta(1).unwrap().unwrap();
assert_eq!(s1.next_slots, vec![2]); assert_eq!(s1.next_slots, vec![2]);
assert!(!s1.is_trunk); assert!(!s1.is_rooted);
assert_eq!(s1.parent_slot, 0); assert_eq!(s1.parent_slot, 0);
assert_eq!(s1.last_index, entries_per_slot - 1); assert_eq!(s1.last_index, entries_per_slot - 1);
@ -2036,7 +2036,7 @@ pub mod tests {
assert_eq!(s.parent_slot, i - 1); assert_eq!(s.parent_slot, i - 1);
} }
assert_eq!(s.last_index, entries_per_slot - 1); assert_eq!(s.last_index, entries_per_slot - 1);
assert!(s.is_trunk); assert!(s.is_rooted);
} }
} }
Blocktree::destroy(&blocktree_path).expect("Expected successful database destruction"); Blocktree::destroy(&blocktree_path).expect("Expected successful database destruction");
@ -2090,9 +2090,9 @@ pub mod tests {
} }
if i == 0 { if i == 0 {
assert!(s.is_trunk); assert!(s.is_rooted);
} else { } else {
assert!(!s.is_trunk); assert!(!s.is_rooted);
} }
} }
@ -2115,7 +2115,7 @@ pub mod tests {
assert_eq!(s.parent_slot, i - 1); assert_eq!(s.parent_slot, i - 1);
} }
assert_eq!(s.last_index, entries_per_slot - 1); assert_eq!(s.last_index, entries_per_slot - 1);
assert!(s.is_trunk); assert!(s.is_rooted);
} }
} }
@ -2123,8 +2123,8 @@ pub mod tests {
} }
#[test] #[test]
pub fn test_forward_chaining_is_trunk() { pub fn test_forward_chaining_is_rooted() {
let blocktree_path = get_tmp_ledger_path("test_forward_chaining_is_trunk"); let blocktree_path = get_tmp_ledger_path("test_forward_chaining_is_rooted");
{ {
let blocktree = Blocktree::open(&blocktree_path).unwrap(); let blocktree = Blocktree::open(&blocktree_path).unwrap();
let num_slots = 15; let num_slots = 15;
@ -2166,9 +2166,9 @@ pub mod tests {
// Other than slot 0, no slots should be part of the trunk // Other than slot 0, no slots should be part of the trunk
if i != 0 { if i != 0 {
assert!(!s.is_trunk); assert!(!s.is_rooted);
} else { } else {
assert!(s.is_trunk); assert!(s.is_rooted);
} }
} }
@ -2186,9 +2186,9 @@ pub mod tests {
assert!(s.next_slots.is_empty()); assert!(s.next_slots.is_empty());
} }
if i <= slot_index as u64 + 3 { if i <= slot_index as u64 + 3 {
assert!(s.is_trunk); assert!(s.is_rooted);
} else { } else {
assert!(!s.is_trunk); assert!(!s.is_rooted);
} }
if i == 0 { if i == 0 {