99
1010use crate :: Block ;
1111use commonware_broadcast:: { buffered, Broadcaster } ;
12- use commonware_codec:: { Encode , EncodeSize , Error as CodecError , Read , ReadExt , Write } ;
12+ use commonware_codec:: { EncodeSize , Error as CodecError , FixedSize , Read , ReadExt , Write } ;
1313use commonware_coding:: reed_solomon:: { self , decode, Chunk , Error as ReedSolomonError } ;
1414use commonware_cryptography:: { Committable , Digestible , Hasher , PublicKey } ;
1515use commonware_p2p:: Recipients ;
6060
6161 /// Open subscriptions for blocks by commitment.
6262 block_subscriptions : BTreeMap < B :: Commitment , BlockSubscription < B > > ,
63-
64- /// Open subscriptions for chunks by commitment and index.
65- chunk_subscriptions : BTreeMap < ( B :: Commitment , u16 ) , ChunkSubscription < H > > ,
6663}
6764
6865impl < P , B , H > ShardLayer < P , B , H >
7774 mailbox,
7875 block_codec_cfg,
7976 block_subscriptions : BTreeMap :: new ( ) ,
80- chunk_subscriptions : BTreeMap :: new ( ) ,
8177 }
8278 }
8379
@@ -135,15 +131,6 @@ where
135131 . map ( |c| c. chunk )
136132 . collect :: < Vec < _ > > ( ) ;
137133
138- // Attempt to resolve any open subscriptions for the chunks we have.
139- for chunk in coded_chunks. iter ( ) {
140- if let Some ( mut subs) = self . chunk_subscriptions . remove ( & ( commitment, chunk. index ) ) {
141- for sub in subs. subscribers . drain ( ..) {
142- let _ = sub. send ( chunk. clone ( ) ) ;
143- }
144- }
145- }
146-
147134 if coded_chunks. len ( ) < min as usize {
148135 // Not enough chunks to recover the block yet.
149136 debug ! (
@@ -206,6 +193,23 @@ where
206193 Ok ( ( ) )
207194 }
208195
196+ pub async fn get_chunk (
197+ & mut self ,
198+ commitment : B :: Commitment ,
199+ index : u16 ,
200+ ) -> 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 ( ) ) ;
205+ self . mailbox
206+ . get ( None , commitment, Some ( index_hash) )
207+ . await
208+ . iter ( )
209+ . cloned ( )
210+ . next ( )
211+ }
212+
209213 /// Subscribes to a chunk by commitment and index with an externally prepared responder.
210214 ///
211215 /// The responder will be sent the chunk when it is available; either instantly (if cached)
@@ -215,25 +219,15 @@ where
215219 & mut self ,
216220 commitment : B :: Commitment ,
217221 index : u16 ,
218- responder : oneshot:: Sender < Chunk < H > > ,
222+ responder : oneshot:: Sender < Shard < B , H > > ,
219223 ) {
220- let available_chunks = self . mailbox . get ( None , commitment, None ) . await ;
221-
222- if let Some ( shard) = available_chunks. iter ( ) . find ( |s| s. chunk . index == index) {
223- let _ = responder. send ( shard. chunk . clone ( ) ) ;
224- return ;
225- }
226-
227- match self . chunk_subscriptions . entry ( ( commitment, index) ) {
228- Entry :: Vacant ( entry) => {
229- entry. insert ( ChunkSubscription {
230- subscribers : vec ! [ responder] ,
231- } ) ;
232- }
233- Entry :: Occupied ( mut entry) => {
234- entry. get_mut ( ) . subscribers . push ( responder) ;
235- }
236- }
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 ( ) ) ;
228+ self . mailbox
229+ . subscribe_prepared ( None , commitment, Some ( index_hash) , responder)
230+ . await ;
237231 }
238232}
239233
@@ -326,9 +320,11 @@ where
326320 type Digest = H :: Digest ;
327321
328322 fn digest ( & self ) -> Self :: Digest {
329- // NOTE: This is a lil weird; only doing this to namespace the shard within the buffered mailbox, such that
330- // shards from separate validators can be enqueued without replacing each other.
331- H :: hash ( self . chunk . encode ( ) . as_ref ( ) )
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 ( ) )
332328 }
333329}
334330
0 commit comments