diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index e666ff1fc8fd9b..e224892376ff15 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -1010,10 +1010,14 @@ impl Blockstore { // are not stored in blockstore. match shred.shred_type() { ShredType::Code => { + // Don't need Arc overhead here! + debug_assert_matches!(shred.payload(), shred::Payload::Unique(_)); recovered_shreds.push(shred.into_payload()); None } ShredType::Data => { + // Verify that the cloning is cheap here. + debug_assert_matches!(shred.payload(), shred::Payload::Shared(_)); recovered_shreds.push(shred.payload().clone()); Some(shred) } diff --git a/ledger/src/shred/merkle.rs b/ledger/src/shred/merkle.rs index 1caae707afd702..9d41997135b233 100644 --- a/ledger/src/shred/merkle.rs +++ b/ledger/src/shred/merkle.rs @@ -1032,7 +1032,11 @@ fn make_stub_shred( Shred::ShredData(ShredData { common_header, data_header, - payload: Payload::from(payload), + // Recovered data shreds are concurrently inserted into blockstore + // while their payload is sent to retransmit-stage. Using a shared + // payload between the two concurrent paths will reduce allocations + // and memcopies. + payload: Payload::from(std::sync::Arc::new(payload)), }) }; if let Some(chained_merkle_root) = chained_merkle_root { @@ -1768,6 +1772,12 @@ mod test { } }); assert_eq!(recovered_shreds, removed_shreds); + for shred in recovered_shreds { + match shred.shred_type() { + ShredType::Code => assert_matches!(shred.payload(), Payload::Unique(_)), + ShredType::Data => assert_matches!(shred.payload(), Payload::Shared(_)), + } + } } } @@ -2095,6 +2105,9 @@ mod test { }) .collect(); assert_eq!(recovered_data_shreds.len(), data_shreds.len()); + for shred in &recovered_data_shreds { + assert_matches!(shred.payload(), Payload::Shared(_)); + } for (shred, other) in recovered_data_shreds.into_iter().zip(data_shreds) { match shred { Shred::ShredCode(_) => panic!("Invalid shred type!"), diff --git a/ledger/src/shred/payload.rs b/ledger/src/shred/payload.rs index 12b9bf3b6989eb..a3aa85acf331ff 100644 --- a/ledger/src/shred/payload.rs +++ b/ledger/src/shred/payload.rs @@ -3,7 +3,7 @@ use std::{ sync::Arc, }; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq)] pub enum Payload { Shared(Arc>), Unique(Vec), @@ -87,6 +87,13 @@ pub(crate) mod serde_bytes_payload { } } +impl PartialEq for Payload { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_ref() == other.as_ref() + } +} + impl From> for Payload { #[inline] fn from(bytes: Vec) -> Self {