Rename SlotMeta::is_trunk to SlotMeta::is_rooted
This commit is contained in:
parent
271115a6be
commit
4704aa1f80
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue