Skip to content

Commit 4d5b7f4

Browse files
committed
lazy re-encode
1 parent e87a951 commit 4d5b7f4

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

consensus/src/marshal/ingress/coding/mailbox.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ where
107107
/// ## Panics
108108
///
109109
/// Panics if the number of `participants` is not equal to the number of [Shard]s in the `block`
110-
pub async fn broadcast_shards(&mut self, block: CodedBlock<B, S>, participants: Vec<P>) {
110+
pub async fn broadcast_shards(&mut self, mut block: CodedBlock<B, S>, participants: Vec<P>) {
111111
assert_eq!(
112112
participants.len(),
113113
block.shards().len(),
@@ -277,7 +277,11 @@ where
277277
.set(start.elapsed().as_millis() as i64);
278278

279279
// Attempt to decode the block from the encoded blob
280-
let block = CodedBlock::<B, S>::decode_cfg(decoded.as_slice(), &self.block_codec_cfg)?;
280+
let inner = B::read_cfg(&mut decoded.as_slice(), &self.block_codec_cfg)?;
281+
282+
// Construct a coding block with a _trusted_ commitment. `S::decode` verified the blob's
283+
// integrity, so shards can be lazily re-constructed if need be.
284+
let block = CodedBlock::new_trusted(inner, commitment);
281285

282286
debug!(
283287
%commitment,

consensus/src/marshal/ingress/coding/types.rs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,10 @@ pub struct CodedBlock<B: Block, S: Scheme> {
229229
config: CodingConfig,
230230
/// The erasure coding commitment.
231231
commitment: S::Commitment,
232-
/// The coded shards, along with corresponding coding proofs.
233-
shards: Vec<S::Shard>,
232+
/// The coded shards.
233+
///
234+
/// These shards are optional to enable lazy construction.
235+
shards: Option<Vec<S::Shard>>,
234236
}
235237

236238
impl<B: Block<Commitment = CodingCommitment>, S: Scheme> CodedBlock<B, S> {
@@ -250,7 +252,17 @@ impl<B: Block<Commitment = CodingCommitment>, S: Scheme> CodedBlock<B, S> {
250252
inner,
251253
config,
252254
commitment,
253-
shards,
255+
shards: Some(shards),
256+
}
257+
}
258+
259+
/// Create a new [CodedBlock] from a [Block] and trusted [CodingCommitment].
260+
pub fn new_trusted(inner: B, commitment: CodingCommitment) -> Self {
261+
Self {
262+
inner,
263+
config: commitment.config(),
264+
commitment: commitment.inner(),
265+
shards: None,
254266
}
255267
}
256268

@@ -260,16 +272,26 @@ impl<B: Block<Commitment = CodingCommitment>, S: Scheme> CodedBlock<B, S> {
260272
}
261273

262274
/// Returns a refernce to the shards in this coded block.
263-
pub fn shards(&self) -> &[S::Shard] {
264-
&self.shards
275+
pub fn shards(&mut self) -> &[S::Shard] {
276+
match self.shards {
277+
Some(ref shards) => shards,
278+
None => {
279+
let (commitment, shards) = Self::encode(&self.inner, self.config);
280+
281+
assert_eq!(commitment, self.commitment);
282+
283+
self.shards = Some(shards);
284+
self.shards.as_ref().unwrap()
285+
}
286+
}
265287
}
266288

267289
/// Returns a [Shard] at the given index, if the index is valid.
268290
pub fn shard<H: Hasher>(&self, index: usize) -> Option<Shard<S, H>> {
269291
Some(Shard::new(
270292
self.commitment(),
271293
index,
272-
DistributionShard::Strong(self.shards.get(index)?.clone()),
294+
DistributionShard::Strong(self.shards.as_ref()?.get(index)?.clone()),
273295
))
274296
}
275297

@@ -345,7 +367,7 @@ impl<B: Block, S: Scheme> Read for CodedBlock<B, S> {
345367
inner,
346368
config,
347369
commitment,
348-
shards,
370+
shards: Some(shards),
349371
})
350372
}
351373
}

0 commit comments

Comments
 (0)