@@ -589,12 +589,13 @@ impl Decode for Vec<ValidatorIndex> {
589589 }
590590}
591591
592- impl Decode for Event {
593- fn decode ( buf : & mut Cursor < & [ u8 ] > ) -> Result < Self , DecodingError > {
592+ impl Event {
593+ /// Decode an event from the wire format, using `core_count` (C) from
594+ /// the node's ProtocolParameters for fixed-size [u8; C] arrays (JIP-3).
595+ pub fn decode_event ( buf : & mut Cursor < & [ u8 ] > , core_count : u16 ) -> Result < Self , DecodingError > {
594596 let timestamp = Timestamp :: decode ( buf) ?;
595597 let discriminator = u8:: decode ( buf) ?;
596598
597- // Debug logging
598599 if ![ 10 , 11 , 12 , 13 ] . contains ( & discriminator) {
599600 tracing:: trace!(
600601 "Decoding event with discriminator: {}, remaining bytes: {}" ,
@@ -614,14 +615,12 @@ impl Decode for Event {
614615 let num_val_peers = u32:: decode ( buf) ?;
615616 let num_sync_peers = u32:: decode ( buf) ?;
616617
617- // TODO: JIP-3 specifies num_guarantees as [u8; C] (fixed-size array where
618- // C = core_count), but PolkaJam sends a varint length prefix before the
619- // byte array. We decode it as variable-length to match actual wire format.
620- let core_count = decode_variable_length ( buf) ? as usize ;
621- let mut num_guarantees = vec ! [ 0u8 ; core_count] ;
622- if buf. remaining ( ) < core_count {
618+ // JIP-3: num_guarantees is [u8; C] — fixed-size array, no length prefix
619+ let c = core_count as usize ;
620+ let mut num_guarantees = vec ! [ 0u8 ; c] ;
621+ if buf. remaining ( ) < c {
623622 return Err ( DecodingError :: InsufficientData {
624- needed : core_count ,
623+ needed : c ,
625624 available : buf. remaining ( ) ,
626625 } ) ;
627626 }
@@ -982,10 +981,24 @@ impl Decode for Event {
982981 } ) ,
983982
984983 // Assurance distribution (126-131)
985- 126 => Ok ( Event :: DistributingAssurance {
986- timestamp,
987- statement : AvailabilityStatement :: decode ( buf) ?,
988- } ) ,
984+ 126 => {
985+ // JIP-3: AvailabilityStatement is anchor (32 bytes) +
986+ // bitfield [u8; ceil(C/8)] — fixed-size, no length prefix
987+ let anchor = HeaderHash :: decode ( buf) ?;
988+ let bitfield_len = ( core_count as usize ) . div_ceil ( 8 ) ;
989+ if buf. remaining ( ) < bitfield_len {
990+ return Err ( DecodingError :: InsufficientData {
991+ needed : bitfield_len,
992+ available : buf. remaining ( ) ,
993+ } ) ;
994+ }
995+ let mut bitfield = vec ! [ 0u8 ; bitfield_len] ;
996+ buf. copy_to_slice ( & mut bitfield) ;
997+ Ok ( Event :: DistributingAssurance {
998+ timestamp,
999+ statement : AvailabilityStatement { anchor, bitfield } ,
1000+ } )
1001+ }
9891002 127 => Ok ( Event :: AssuranceSendFailed {
9901003 timestamp,
9911004 distributing_id : EventId :: decode ( buf) ?,
@@ -1245,6 +1258,15 @@ impl Decode for Event {
12451258 }
12461259}
12471260
1261+ impl Decode for Event {
1262+ fn decode ( buf : & mut Cursor < & [ u8 ] > ) -> Result < Self , DecodingError > {
1263+ // Fallback: decode with core_count=0 (Status/DistributingAssurance will
1264+ // produce empty arrays). Use decode_event() directly with the real
1265+ // core_count for production decoding.
1266+ Event :: decode_event ( buf, 0 )
1267+ }
1268+ }
1269+
12481270pub fn decode_message_frame ( data : & [ u8 ] ) -> Result < ( u32 , & [ u8 ] ) , DecodingError > {
12491271 if data. len ( ) < 4 {
12501272 return Err ( DecodingError :: InsufficientData {
0 commit comments