77use std:: convert:: Infallible ;
88
99use anyhow:: { Context , ensure} ;
10+ use catalyst_types:: uuid:: { self , CborContext , UuidV7 } ;
1011use ed25519_dalek:: VerifyingKey ;
11- use minicbor:: {
12- Decode , Encode , Encoder ,
13- data:: { Tag , Type } ,
14- encode:: Write ,
15- } ;
16- use uuid:: Timestamp ;
12+ use minicbor:: { Decode , Encode , Encoder , data:: Type , encode:: Write } ;
1713
1814use crate :: doc_sync:: PROTOCOL_VERSION ;
1915
20- /// CBOR semantic tag value used for UUIDs (`#6.37`).
21- const CBOR_TAG_UUID : u64 = 37 ;
22-
2316/// Ed25519 public key instance.
2417/// Wrapper over `ed25519_dalek::VerifyingKey`.
2518#[ derive( Clone , Debug , PartialEq , Eq ) ]
@@ -78,53 +71,6 @@ impl<'b, C> Decode<'b, C> for Signature {
7871 }
7972}
8073
81- /// New type wrapper.
82- struct UUIDv7 ( uuid:: Uuid ) ;
83-
84- impl UUIDv7 {
85- /// Create a new version 7 UUID using a time value and random bytes.
86- fn new ( timestamp : Timestamp ) -> Self {
87- Self ( uuid:: Uuid :: new_v7 ( timestamp) )
88- }
89-
90- /// Create a new version 7 UUID using the current time value.
91- fn now ( ) -> Self {
92- Self ( uuid:: Uuid :: now_v7 ( ) )
93- }
94- }
95-
96- impl < C > Encode < C > for UUIDv7 {
97- fn encode < W : Write > (
98- & self ,
99- e : & mut Encoder < W > ,
100- _ctx : & mut C ,
101- ) -> Result < ( ) , minicbor:: encode:: Error < W :: Error > > {
102- e. tag ( Tag :: new ( CBOR_TAG_UUID ) ) ?;
103- e. bytes ( self . 0 . as_bytes ( ) ) ?;
104- Ok ( ( ) )
105- }
106- }
107-
108- impl < ' b , C > Decode < ' b , C > for UUIDv7 {
109- fn decode (
110- d : & mut minicbor:: Decoder < ' b > ,
111- _ctx : & mut C ,
112- ) -> Result < Self , minicbor:: decode:: Error > {
113- let tag = d. tag ( ) ?;
114- if tag != Tag :: new ( CBOR_TAG_UUID ) {
115- return Err ( minicbor:: decode:: Error :: message ( format ! (
116- "UUIDv7 must be tagged with #{CBOR_TAG_UUID}, got #{}" ,
117- u64 :: from( tag)
118- ) ) ) ;
119- }
120- uuid:: Uuid :: from_slice ( d. bytes ( ) ?)
121- . map_err ( |err| {
122- minicbor:: decode:: Error :: message ( format ! ( "error during UUIDv7 decode: {err}" ) )
123- } )
124- . map ( UUIDv7 )
125- }
126- }
127-
12874/// The unsigned portion of the message envelope.
12975/// This structure corresponds to the **signature input** array:
13076/// `[peer, seq, ver, payload]`.
@@ -137,7 +83,7 @@ pub struct EnvelopePayload {
13783 peer : PublicKey ,
13884 /// Unique nonce and timestamp.
13985 /// Prevents and helps detect message duplication.
140- seq : UUIDv7 ,
86+ seq : UuidV7 ,
14187 /// Protocol version number.
14288 /// This should be `1` for the current specification.
14389 ver : u64 ,
@@ -152,32 +98,13 @@ impl EnvelopePayload {
15298 ///
15399 /// Returns an error when `payload` is not a single CBOR map.
154100 pub fn new (
155- peer : ed25519_dalek:: VerifyingKey ,
156- seq : Timestamp ,
157- payload : Vec < u8 > ,
158- ) -> anyhow:: Result < Self > {
159- ensure_payload_body ( & payload) ?;
160- Ok ( Self {
161- peer : PublicKey ( peer) ,
162- seq : UUIDv7 :: new ( seq) ,
163- ver : PROTOCOL_VERSION ,
164- payload,
165- } )
166- }
167-
168- /// Create new instance of `EnvelopePayload` using the current time value.
169- ///
170- /// # Errors
171- ///
172- /// Returns an error when `payload` is not a single CBOR map.
173- pub fn now (
174101 peer : ed25519_dalek:: VerifyingKey ,
175102 payload : Vec < u8 > ,
176103 ) -> anyhow:: Result < Self > {
177104 ensure_payload_body ( & payload) ?;
178105 Ok ( Self {
179106 peer : PublicKey ( peer) ,
180- seq : UUIDv7 :: now ( ) ,
107+ seq : UuidV7 :: new ( ) ,
181108 ver : PROTOCOL_VERSION ,
182109 payload,
183110 } )
@@ -189,10 +116,10 @@ impl EnvelopePayload {
189116 & self . peer . 0
190117 }
191118
192- /// Returns the `UUIDv7 ` sequence value.
119+ /// Returns the `UuidV7 ` sequence value.
193120 #[ must_use]
194- pub fn seq ( & self ) -> & uuid:: Uuid {
195- & self . seq . 0
121+ pub fn seq ( & self ) -> uuid:: Uuid {
122+ self . seq . uuid ( )
196123 }
197124
198125 /// Returns the encoded payload-body bytes.
@@ -209,16 +136,16 @@ impl EnvelopePayload {
209136 ///
210137 /// Returns an error if encoding fails (should not happen with `Vec<u8>` writers).
211138 pub fn to_bytes ( & self ) -> Result < Vec < u8 > , minicbor:: encode:: Error < Infallible > > {
212- minicbor:: to_vec ( self )
139+ minicbor:: to_vec_with ( self , & mut CborContext :: Tagged )
213140 }
214141
215142 /// Decodes `[peer, seq, ver, payload]` from the signed payload array.
216- fn decode_from_signed < C > (
143+ fn decode_from_signed (
217144 decoder : & mut minicbor:: Decoder < ' _ > ,
218- ctx : & mut C ,
145+ ctx : & mut CborContext ,
219146 ) -> Result < Self , minicbor:: decode:: Error > {
220147 let peer: PublicKey = decoder. decode_with ( ctx) ?;
221- let seq: UUIDv7 = decoder. decode_with ( ctx) ?;
148+ let seq: UuidV7 = decoder. decode_with ( ctx) ?;
222149 let ver = decoder. u64 ( ) ?;
223150
224151 if ver != PROTOCOL_VERSION {
@@ -251,24 +178,26 @@ impl EnvelopePayload {
251178 }
252179}
253180
254- impl < C > Encode < C > for EnvelopePayload {
181+ impl Encode < CborContext > for EnvelopePayload {
255182 fn encode < W : Write > (
256183 & self ,
257184 e : & mut Encoder < W > ,
258- _ctx : & mut C ,
185+ ctx : & mut CborContext ,
259186 ) -> Result < ( ) , minicbor:: encode:: Error < W :: Error > > {
260187 e. array ( 4 ) ?;
261- e. encode ( & self . peer ) ?. encode ( & self . seq ) ?. u64 ( self . ver ) ?;
188+ e. encode ( & self . peer ) ?
189+ . encode_with ( self . seq , ctx) ?
190+ . u64 ( self . ver ) ?;
262191 <W as Write >:: write_all ( e. writer_mut ( ) , & self . payload )
263192 . map_err ( minicbor:: encode:: Error :: write) ?;
264193 Ok ( ( ) )
265194 }
266195}
267196
268- impl < ' b , C > Decode < ' b , C > for EnvelopePayload {
197+ impl < ' b > Decode < ' b , CborContext > for EnvelopePayload {
269198 fn decode (
270199 d : & mut minicbor:: Decoder < ' b > ,
271- ctx : & mut C ,
200+ ctx : & mut CborContext ,
272201 ) -> Result < Self , minicbor:: decode:: Error > {
273202 let len = d. array ( ) ?;
274203 match len {
@@ -286,7 +215,7 @@ impl<'b, C> Decode<'b, C> for EnvelopePayload {
286215 }
287216
288217 let peer: PublicKey = d. decode_with ( ctx) ?;
289- let seq: UUIDv7 = d. decode_with ( ctx) ?;
218+ let seq: UuidV7 = d. decode_with ( ctx) ?;
290219 let ver = d. u64 ( ) ?;
291220
292221 if ver != PROTOCOL_VERSION {
@@ -393,7 +322,7 @@ impl Envelope {
393322 let mut encoder = Encoder :: new ( Vec :: new ( ) ) ;
394323 encoder. array ( 5 ) ?;
395324 encoder. encode ( & self . payload . peer ) ?;
396- encoder. encode ( & self . payload . seq ) ?;
325+ encoder. encode_with ( self . payload . seq , & mut CborContext :: Tagged ) ?;
397326 encoder. u64 ( self . payload . ver ) ?;
398327 encoder
399328 . writer_mut ( )
@@ -419,10 +348,10 @@ impl<C> Encode<C> for Envelope {
419348 }
420349}
421350
422- impl < ' b , C > Decode < ' b , C > for Envelope {
351+ impl < ' b > Decode < ' b , CborContext > for Envelope {
423352 fn decode (
424353 d : & mut minicbor:: Decoder < ' b > ,
425- ctx : & mut C ,
354+ ctx : & mut CborContext ,
426355 ) -> Result < Self , minicbor:: decode:: Error > {
427356 let signed_payload_bytes = d. bytes ( ) ?;
428357 let mut signed_decoder = minicbor:: Decoder :: new ( signed_payload_bytes) ;
@@ -490,7 +419,7 @@ mod tests {
490419 fn envelope_roundtrip_matches_spec_bstr ( ) {
491420 let signing_key = signing_key ( ) ;
492421 let payload_body = sample_payload_body ( ) ;
493- let payload = EnvelopePayload :: now ( signing_key. verifying_key ( ) , payload_body. clone ( ) )
422+ let payload = EnvelopePayload :: new ( signing_key. verifying_key ( ) , payload_body. clone ( ) )
494423 . expect ( "payload" ) ;
495424
496425 let signature = signing_key
@@ -512,8 +441,9 @@ mod tests {
512441
513442 // Decode fully to ensure `Decode` impl works.
514443 let mut envelope_decoder = Decoder :: new ( & encoded) ;
515- let mut ctx = ( ) ;
516- let decoded: Envelope = envelope_decoder. decode_with ( & mut ctx) . expect ( "decode" ) ;
444+ let decoded: Envelope = envelope_decoder
445+ . decode_with ( & mut CborContext :: Tagged )
446+ . expect ( "decode" ) ;
517447 assert_eq ! ( decoded. payload( ) . payload_bytes( ) , payload_body. as_slice( ) ) ;
518448 }
519449
@@ -522,7 +452,7 @@ mod tests {
522452 let signing_key = signing_key ( ) ;
523453 let payload_body = sample_payload_body ( ) ;
524454 let payload =
525- EnvelopePayload :: now ( signing_key. verifying_key ( ) , payload_body) . expect ( "payload" ) ;
455+ EnvelopePayload :: new ( signing_key. verifying_key ( ) , payload_body) . expect ( "payload" ) ;
526456
527457 let signature = signing_key
528458 . try_sign ( & payload. to_bytes ( ) . expect ( "bytes" ) )
@@ -531,7 +461,9 @@ mod tests {
531461 let mut signed = Encoder :: new ( Vec :: new ( ) ) ;
532462 signed. array ( 5 ) . unwrap ( ) ;
533463 signed. encode ( & payload. peer ) . unwrap ( ) ;
534- signed. encode ( & payload. seq ) . unwrap ( ) ;
464+ signed
465+ . encode_with ( payload. seq , & mut CborContext :: Tagged )
466+ . unwrap ( ) ;
535467 signed. u64 ( PROTOCOL_VERSION + 1 ) . unwrap ( ) ;
536468 <Vec < u8 > as Write >:: write_all ( signed. writer_mut ( ) , & payload. payload ) . unwrap ( ) ;
537469 signed. encode ( Signature ( signature) ) . unwrap ( ) ;
@@ -541,8 +473,7 @@ mod tests {
541473 let bytes = envelope. into_writer ( ) ;
542474
543475 let mut decoder = Decoder :: new ( & bytes) ;
544- let mut ctx = ( ) ;
545- let result: Result < Envelope , _ > = decoder. decode_with ( & mut ctx) ;
476+ let result: Result < Envelope , _ > = decoder. decode_with ( & mut CborContext :: Tagged ) ;
546477 assert ! ( result. is_err( ) , "expected version mismatch error" ) ;
547478 }
548479
@@ -551,7 +482,7 @@ mod tests {
551482 let signing_key = signing_key ( ) ;
552483 let payload_body = sample_payload_body ( ) ;
553484 let payload =
554- EnvelopePayload :: now ( signing_key. verifying_key ( ) , payload_body) . expect ( "payload" ) ;
485+ EnvelopePayload :: new ( signing_key. verifying_key ( ) , payload_body) . expect ( "payload" ) ;
555486
556487 let mut signature = signing_key
557488 . try_sign ( & payload. to_bytes ( ) . expect ( "bytes" ) )
@@ -572,30 +503,7 @@ mod tests {
572503 enc. u8 ( 42 ) . unwrap ( ) ;
573504 let payload_bytes = enc. into_writer ( ) ;
574505
575- let result = EnvelopePayload :: now ( signing_key. verifying_key ( ) , payload_bytes) ;
506+ let result = EnvelopePayload :: new ( signing_key. verifying_key ( ) , payload_bytes) ;
576507 assert ! ( result. is_err( ) , "non-map payload must be rejected" ) ;
577508 }
578-
579- #[ test]
580- fn uuidv7_uses_cbor_tag_37 ( ) {
581- let seq = UUIDv7 :: now ( ) ;
582- let bytes = minicbor:: to_vec ( & seq) . expect ( "encode" ) ;
583-
584- let mut decoder = Decoder :: new ( & bytes) ;
585- let tag = decoder. tag ( ) . expect ( "tag" ) ;
586- assert_eq ! ( u64 :: from( tag) , CBOR_TAG_UUID ) ;
587- }
588-
589- #[ test]
590- fn uuidv7_decode_rejects_missing_tag ( ) {
591- let seq = UUIDv7 :: now ( ) ;
592- let mut encoder = Encoder :: new ( Vec :: new ( ) ) ;
593- encoder. bytes ( seq. 0 . as_bytes ( ) ) . expect ( "bytes" ) ;
594- let bytes = encoder. into_writer ( ) ;
595-
596- let mut decoder = Decoder :: new ( & bytes) ;
597- let mut ctx = ( ) ;
598- let result: Result < UUIDv7 , _ > = decoder. decode_with ( & mut ctx) ;
599- assert ! ( result. is_err( ) , "untagged UUID must be rejected" ) ;
600- }
601509}
0 commit comments