@@ -10,17 +10,17 @@ use crate::{
1010 hpke_receiver_config:: { self , hpke_config} ,
1111 initialize_reports,
1212 initialized_reports:: { self , initialized_report} ,
13- partial_dap_task_config, prepare_init, report_metadata, time_range,
13+ partial_dap_task_config, prepare_init, public_extensions_list , report_metadata, time_range,
1414 } ,
1515} ;
1616use daphne:: {
1717 constants:: DapAggregatorRole ,
1818 hpke:: { HpkeConfig , HpkeReceiverConfig } ,
19- messages:: { self , HpkeCiphertext , PrepareInit , ReportMetadata , ReportShare , TaskId } ,
19+ messages:: { self , Extension , HpkeCiphertext , PrepareInit , ReportMetadata , ReportShare , TaskId } ,
2020 vdaf:: { VdafConfig , VdafPrepShare , VdafPrepState } ,
2121 InitializedReport , PartialDapTaskConfigForReportInit , WithPeerPrepShare ,
2222} ;
23- use prio:: codec:: { Encode , ParameterizedDecode , ParameterizedEncode } ;
23+ use prio:: codec:: { Decode , Encode , ParameterizedDecode , ParameterizedEncode } ;
2424use std:: { borrow:: Cow , ops:: Range } ;
2525
2626pub struct InitializeReports < ' s > {
@@ -318,9 +318,27 @@ impl CapnprotoPayloadEncode for ReportMetadata {
318318 type Builder < ' a > = report_metadata:: Builder < ' a > ;
319319
320320 fn encode_to_builder ( & self , mut builder : Self :: Builder < ' _ > ) {
321- let Self { id, time } = self ;
321+ let Self {
322+ id,
323+ time,
324+ public_extensions,
325+ } = self ;
322326 id. encode_to_builder ( builder. reborrow ( ) . init_id ( ) ) ;
323327 builder. set_time ( * time) ;
328+ if let Some ( ref extensions) = public_extensions {
329+ let mut e = builder
330+ . init_public_extensions ( )
331+ . init_list ( usize_to_capnp_len ( extensions. len ( ) ) ) ;
332+ for ( i, data) in extensions
333+ . iter ( )
334+ . enumerate ( )
335+ . map ( |( i, ext) | ( usize_to_capnp_len ( i) , ext. get_encoded ( ) . unwrap ( ) ) )
336+ {
337+ e. reborrow ( ) . set ( i, & data) ;
338+ }
339+ } else {
340+ builder. init_public_extensions ( ) . set_none ( ( ) ) ;
341+ }
324342 }
325343}
326344
@@ -331,9 +349,25 @@ impl CapnprotoPayloadDecode for ReportMetadata {
331349 where
332350 Self : Sized ,
333351 {
352+ let id = <_ >:: decode_from_reader ( reader. get_id ( ) ?) ?;
353+ let time = reader. get_time ( ) ;
354+ let public_extensions = match reader. get_public_extensions ( ) ?. which ( ) ? {
355+ public_extensions_list:: List ( list) => Some (
356+ list?
357+ . into_iter ( )
358+ . map ( |data| {
359+ Extension :: get_decoded ( data?)
360+ . map_err ( |e| capnp:: Error :: failed ( e. to_string ( ) ) )
361+ } )
362+ . collect :: < Result < Vec < _ > , capnp:: Error > > ( ) ?,
363+ ) ,
364+ public_extensions_list:: None ( ( ) ) => None ,
365+ } ;
366+
334367 Ok ( Self {
335- id : <_ >:: decode_from_reader ( reader. get_id ( ) ?) ?,
336- time : reader. get_time ( ) ,
368+ id,
369+ time,
370+ public_extensions,
337371 } )
338372 }
339373}
@@ -486,3 +520,45 @@ fn to_capnp<E: ToString>(e: E) -> capnp::Error {
486520 extra : e. to_string ( ) ,
487521 }
488522}
523+
524+ #[ cfg( test) ]
525+ mod test {
526+ use super :: * ;
527+ use crate :: capnproto:: { CapnprotoPayloadDecodeExt , CapnprotoPayloadEncodeExt } ;
528+
529+ #[ test]
530+ fn report_metadata_roundtrip ( ) {
531+ let report_metadata = ReportMetadata {
532+ id : messages:: ReportId ( rand:: random ( ) ) ,
533+ time : rand:: random ( ) ,
534+ public_extensions : Some ( vec ! [
535+ Extension :: Taskprov ,
536+ Extension :: NotImplemented {
537+ typ: 23 ,
538+ payload: b"some extension payload" . to_vec( ) ,
539+ } ,
540+ ] ) ,
541+ } ;
542+
543+ assert_eq ! (
544+ report_metadata,
545+ ReportMetadata :: decode_from_bytes( & report_metadata. encode_to_bytes( ) ) . unwrap( )
546+ ) ;
547+ }
548+
549+ #[ test]
550+ fn report_metadata_roundtrip_draft09 ( ) {
551+ let report_metadata = ReportMetadata {
552+ id : messages:: ReportId ( rand:: random ( ) ) ,
553+ time : rand:: random ( ) ,
554+ // draft09 compatibility: Previously there was no extensions field in the report
555+ // metadata.
556+ public_extensions : None ,
557+ } ;
558+
559+ assert_eq ! (
560+ report_metadata,
561+ ReportMetadata :: decode_from_bytes( & report_metadata. encode_to_bytes( ) ) . unwrap( )
562+ ) ;
563+ }
564+ }
0 commit comments