Skip to content

Commit 2edcf84

Browse files
committed
api cleanup
1 parent ad6e255 commit 2edcf84

File tree

3 files changed

+49
-49
lines changed

3 files changed

+49
-49
lines changed

consensus/src/marshal/actor.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::{
1515
Block, Reporter,
1616
};
1717
use commonware_codec::{Decode, Encode};
18-
use commonware_coding::reed_solomon::Chunk;
1918
use commonware_cryptography::{
2019
bls12381::primitives::variant::Variant, Committable, Hasher, PublicKey,
2120
};

consensus/src/marshal/ingress/coding.rs

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ struct BlockSubscription<B: Block> {
3939
subscribers: Vec<oneshot::Sender<B>>,
4040
}
4141

42-
/// A subscription for a chunk by its commitment and index.
43-
struct ChunkSubscription<H: Hasher> {
44-
subscribers: Vec<oneshot::Sender<Chunk<H>>>,
45-
}
46-
4742
/// A layer that handles receiving erasure coded [Block]s from the [Actor](super::super::actor::Actor),
4843
/// broadcasting them to peers, and reassembling them from received [Shard]s.
4944
pub struct ShardLayer<P, B, H>
@@ -131,6 +126,9 @@ where
131126
.map(|c| c.chunk)
132127
.collect::<Vec<_>>();
133128

129+
// TODO: Make sure min is all valid chunks
130+
// TODO: If we do encounter a block that's invalid, block the peer.
131+
134132
if coded_chunks.len() < min as usize {
135133
// Not enough chunks to recover the block yet.
136134
debug!(
@@ -149,9 +147,9 @@ where
149147
// Attempt to decode the block from the recovered data.
150148
let block = B::decode_cfg(&mut recovered.as_slice(), &self.block_codec_cfg)?;
151149

152-
// Attempt to resolve any open subscriptions for this block.
153-
if let Some(mut subs) = self.block_subscriptions.remove(&commitment) {
154-
for sub in subs.subscribers.drain(..) {
150+
// Notify any subscribers that have been waiting for this block.
151+
if let Some(mut sub) = self.block_subscriptions.remove(&commitment) {
152+
for sub in sub.subscribers.drain(..) {
155153
let _ = sub.send(block.clone());
156154
}
157155
}
@@ -198,10 +196,7 @@ where
198196
commitment: B::Commitment,
199197
index: u16,
200198
) -> Option<Shard<B, H>> {
201-
let mut buf = vec![0u8; <H::Digest as FixedSize>::SIZE + 2];
202-
buf[..<H::Digest as FixedSize>::SIZE].copy_from_slice(commitment.as_ref());
203-
buf[<H::Digest as FixedSize>::SIZE..].copy_from_slice(index.to_le_bytes().as_ref());
204-
let index_hash = H::hash(buf.as_ref());
199+
let index_hash = shard_uuid::<B, H>(commitment, index);
205200
self.mailbox
206201
.get(None, commitment, Some(index_hash))
207202
.await
@@ -221,10 +216,7 @@ where
221216
index: u16,
222217
responder: oneshot::Sender<Shard<B, H>>,
223218
) {
224-
let mut buf = vec![0u8; <H::Digest as FixedSize>::SIZE + 2];
225-
buf[..<H::Digest as FixedSize>::SIZE].copy_from_slice(commitment.as_ref());
226-
buf[<H::Digest as FixedSize>::SIZE..].copy_from_slice(index.to_le_bytes().as_ref());
227-
let index_hash = H::hash(buf.as_ref());
219+
let index_hash = shard_uuid::<B, H>(commitment, index);
228220
self.mailbox
229221
.subscribe_prepared(None, commitment, Some(index_hash), responder)
230222
.await;
@@ -320,11 +312,7 @@ where
320312
type Digest = H::Digest;
321313

322314
fn digest(&self) -> Self::Digest {
323-
let mut buf = vec![0u8; <H::Digest as FixedSize>::SIZE + 2];
324-
buf[..<H::Digest as FixedSize>::SIZE].copy_from_slice(self.commitment.as_ref());
325-
buf[<H::Digest as FixedSize>::SIZE..]
326-
.copy_from_slice(self.chunk.index.to_le_bytes().as_ref());
327-
H::hash(buf.as_ref())
315+
shard_uuid::<B, H>(self.commitment, self.chunk.index)
328316
}
329317
}
330318

@@ -407,31 +395,32 @@ where
407395
config: (u16, u16),
408396
/// The erasure coding commitment.
409397
commitment: H::Digest,
398+
/// The coded chunks.
399+
chunks: Vec<Chunk<H>>,
410400
}
411401

412402
impl<B, H> CodedBlock<B, H>
413403
where
414404
B: Block<Digest = H::Digest, Commitment = H::Digest>,
415405
H: Hasher,
416406
{
417-
/// Erasure codes the block to create the commitment.
418-
fn commit(inner: &B, config: (u16, u16)) -> H::Digest {
407+
/// Erasure codes the block.
408+
fn encode(inner: &B, config: (u16, u16)) -> (H::Digest, Vec<Chunk<H>>) {
419409
let mut buf = Vec::with_capacity(config.encode_size() + inner.encode_size());
420410
inner.write(&mut buf);
421411
config.write(&mut buf);
422412

423-
let (commitment, _) =
424-
reed_solomon::encode::<H>(config.0, config.1, buf).expect("failed to commit to block");
425-
commitment
413+
reed_solomon::encode::<H>(config.0, config.1, buf).expect("failed to commit to block")
426414
}
427415

428416
/// Create a new [CodedBlock] from a [Block] and a configuration.
429417
pub fn new(inner: B, config: (u16, u16)) -> Self {
430-
let commitment = Self::commit(&inner, config);
418+
let (commitment, chunks) = Self::encode(&inner, config);
431419
Self {
432420
inner,
433421
config,
434422
commitment,
423+
chunks,
435424
}
436425
}
437426

@@ -444,6 +433,16 @@ where
444433
pub fn take_inner(self) -> B {
445434
self.inner
446435
}
436+
437+
/// Returns the erasure coding configuration.
438+
pub fn config(&self) -> (u16, u16) {
439+
self.config
440+
}
441+
442+
/// Returns a reference to the coded chunks.
443+
pub fn chunks(&self) -> &[Chunk<H>] {
444+
self.chunks.as_slice()
445+
}
447446
}
448447

449448
impl<B, H> Write for CodedBlock<B, H>
@@ -470,12 +469,13 @@ where
470469
) -> Result<Self, commonware_codec::Error> {
471470
let inner = B::read_cfg(buf, cfg)?;
472471
let config = <(u16, u16)>::read_cfg(buf, &((), ()))?;
473-
let commitment = Self::commit(&inner, config);
472+
let (commitment, chunks) = Self::encode(&inner, config);
474473

475474
Ok(Self {
476475
inner,
477476
config,
478477
commitment,
478+
chunks,
479479
})
480480
}
481481
}
@@ -547,6 +547,18 @@ where
547547
{
548548
}
549549

550+
/// Creates a unique identifier for a shard based on the block commitment and shard index.
551+
fn shard_uuid<B, H>(commitment: B::Commitment, index: u16) -> H::Digest
552+
where
553+
B: Block<Digest = H::Digest, Commitment = H::Digest>,
554+
H: Hasher,
555+
{
556+
let mut buf = vec![0u8; H::Digest::SIZE + u16::SIZE];
557+
buf[..H::Digest::SIZE].copy_from_slice(commitment.as_ref());
558+
buf[H::Digest::SIZE..].copy_from_slice(index.to_le_bytes().as_ref());
559+
H::hash(buf.as_ref())
560+
}
561+
550562
#[cfg(test)]
551563
mod test {
552564
use super::*;

consensus/src/marshal/mod.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -334,19 +334,6 @@ mod tests {
334334
}
335335
}
336336

337-
#[allow(clippy::type_complexity)]
338-
fn shard(block: &B, peers: &[P]) -> (D, (u16, u16), Vec<(P, Chunk<H>)>) {
339-
let (total, min) = (peers.len() as u16, peers.len() as u16 / 2);
340-
let block = CodedBlock::<B, H>::new(block.clone(), (total, min));
341-
let (commitment, chunks) =
342-
reed_solomon::encode::<H>(total, min, block.encode().into()).unwrap();
343-
(
344-
commitment,
345-
(total, min),
346-
peers.iter().cloned().zip(chunks).collect(),
347-
)
348-
}
349-
350337
#[test_traced("DEBUG")]
351338
fn test_finalize_good_links() {
352339
for seed in 0..5 {
@@ -401,14 +388,14 @@ mod tests {
401388
setup_network_links(&mut oracle, &peers, link.clone()).await;
402389

403390
// Generate blocks, skipping the genesis block.
404-
let mut blocks = Vec::<B>::new();
391+
let mut blocks = Vec::<CodedBlock<B, H>>::new();
405392
let mut parent = Sha256::hash(b"");
406393
let (total, min) = (peers.len() as u16, (peers.len() / 2) as u16);
407394
for i in 1..=NUM_BLOCKS {
408-
let block = Block::new::<Sha256>(parent, i, i);
409-
let block = CodedBlock::<B, H>::new(block, (total, min));
395+
let inner = Block::new::<Sha256>(parent, i, i);
396+
let block = CodedBlock::<B, H>::new(inner, (total, min));
410397
parent = block.commitment();
411-
blocks.push(block.take_inner());
398+
blocks.push(block);
412399
}
413400

414401
// Broadcast and finalize blocks in random order
@@ -426,8 +413,10 @@ mod tests {
426413
let actor_index: usize = (height % (NUM_VALIDATORS as u64)) as usize;
427414
let mut actor = actors[actor_index].clone();
428415

429-
let (commitment, config, chunks) = shard(block, &peers);
430-
actor.broadcast(commitment, config, chunks).await;
416+
let peers_and_chunks = peers.iter().cloned().zip(block.chunks().to_vec()).collect();
417+
actor
418+
.broadcast(block.commitment(), block.config(), peers_and_chunks)
419+
.await;
431420

432421
// Wait for the block chunks to be delivered; Before making notarization votes,
433422
// the chunks must be present.
@@ -436,7 +425,7 @@ mod tests {
436425
let proposal = Proposal {
437426
round,
438427
parent: height.checked_sub(1).unwrap(),
439-
payload: commitment,
428+
payload: block.commitment(),
440429
};
441430

442431
// All validators send a notarization for the block.

0 commit comments

Comments
 (0)