Skip to content

Commit

Permalink
dedups shreds by common-header instead of entire payload
Browse files Browse the repository at this point in the history
Shreds in the retransmit stage:
  * don't have repair nonce (repaired shreds are not retransmitted).
  * are already resigned by this node as the retransmitter.
  * have their leader's signature verified.
Therefore in order to dedup shreds, it suffices to compare:

    (signature, slot, shred-index, shred-type)

Because ShredCommonHeader already includes all of the above tuple,
the rest of the payload can be skipped.
  • Loading branch information
behzadnouri committed Dec 20, 2024
1 parent ee31e31 commit 6686e09
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
5 changes: 5 additions & 0 deletions ledger/src/shred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,11 @@ pub mod layout {
packet.buffer_mut().get_mut(..size)
}

#[inline]
pub fn get_common_header_bytes(shred: &[u8]) -> Option<&[u8]> {
shred.get(..SIZE_OF_COMMON_SHRED_HEADER)
}

pub(crate) fn get_signature(shred: &[u8]) -> Option<Signature> {
shred
.get(..SIZE_OF_SIGNATURE)
Expand Down
14 changes: 13 additions & 1 deletion turbine/src/retransmit_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,22 @@ impl<const K: usize> ShredDeduper<K> {
.maybe_reset(rng, false_positive_rate, reset_cycle);
}

// Returns true if the shred is duplicate and should be discarded.
#[must_use]
fn dedup(&self, key: ShredId, shred: &[u8], max_duplicate_count: usize) -> bool {
// Shreds in the retransmit stage:
// * don't have repair nonce (repaired shreds are not retransmitted).
// * are already resigned by this node as the retransmitter.
// * have their leader's signature verified.
// Therefore in order to dedup shreds, it suffices to compare:
// (signature, slot, shred-index, shred-type)
// Because ShredCommonHeader already includes all of the above tuple,
// the rest of the payload can be skipped.
// In order to detect duplicate blocks across cluster, we retransmit
// max_duplicate_count different shreds for each ShredId.
self.deduper.dedup(shred)
shred::layout::get_common_header_bytes(shred)
.map(|header| self.deduper.dedup(header))
.unwrap_or(true)
|| (0..max_duplicate_count).all(|i| self.shred_id_filter.dedup(&(key, i)))
}
}
Expand Down

0 comments on commit 6686e09

Please sign in to comment.