@@ -32,16 +32,15 @@ impl From<PermissionedCandidateDatumV1> for PermissionedCandidateData {
3232 // with T: OpaqueKeys, this function will be re-implemented.
3333 fn from ( value : PermissionedCandidateDatumV1 ) -> Self {
3434 let PermissionedCandidateDatumV1 { partner_chains_key, keys } = value;
35- let sidechain_public_key = SidechainPublicKey ( partner_chains_key. bytes ) ;
36- PermissionedCandidateData { sidechain_public_key, keys }
35+ PermissionedCandidateData { sidechain_public_key : partner_chains_key, keys }
3736 }
3837}
3938
4039#[ derive( Clone , Debug , PartialEq ) ]
4140/// Datum representing a permissioned candidate with arbitrary set of keys
4241pub struct PermissionedCandidateDatumV1 {
4342 /// Partner Chains key identifier and bytes
44- pub partner_chains_key : CandidateKey ,
43+ pub partner_chains_key : SidechainPublicKey ,
4544 /// Represents arbitrary set of keys with 4 character identifier
4645 pub keys : CandidateKeys ,
4746}
@@ -75,11 +74,12 @@ impl From<PermissionedCandidateDatums> for Vec<PermissionedCandidateData> {
7574}
7675
7776/// Converts a list of [PermissionedCandidateData] values to [VersionedGenericDatum] encoded as [PlutusData].
78- ///
77+ /// Version 0 is used for specific set of Partner Chains Key: partner chains key, AURA, Grandpa
78+ /// If other set of key is used, then version 1 is used.
7979/// Encoding:
8080/// ```ignore
8181/// VersionedGenericDatum:
82- /// - datum: ()
82+ /// - datum: Constr 0 []
8383/// - appendix:
8484/// [
8585/// [ candidates[0].sidechain_public_key
@@ -94,31 +94,89 @@ impl From<PermissionedCandidateDatums> for Vec<PermissionedCandidateData> {
9494/// // etc.
9595/// ]
9696/// - version: 0
97+ /// or:
98+ /// VersionedGenericDatum:
99+ /// - datum: Constr 0 []
100+ /// - appendix:
101+ /// [
102+ /// [ candidates[0].sidechain_public_key
103+ /// ,
104+ /// [
105+ /// [ candidates[0].keys[0].id,
106+ /// , candidates[0].keys[0].bytes
107+ /// ]
108+ /// , [ candidates[0].keys[1].id,
109+ /// , candidates[0].keys[1].bytes
110+ /// ]
111+ /// // etc.
112+ /// ]
113+ /// ]
114+ /// ,
115+ /// [ candidates[1].sidechain_public_key
116+ /// ,
117+ /// [
118+ /// [ candidates[1].keys[0].id,
119+ /// , candidates[1].keys[0].bytes
120+ /// ]
121+ /// , [ candidates[1].keys[1].id,
122+ /// , candidates[1].keys[1].bytes
123+ /// ]
124+ /// // etc.
125+ /// ]
126+ /// ]
127+ /// // etc.
128+ /// ]
129+ /// - version: 1
97130/// ```
131+
98132pub fn permissioned_candidates_to_plutus_data (
99133 candidates : & [ PermissionedCandidateData ] ,
100134) -> PlutusData {
101- let mut list = PlutusList :: new ( ) ;
102- for candidate in candidates {
103- let mut candidate_datum = PlutusList :: new ( ) ;
104- candidate_datum. add ( & PlutusData :: new_bytes ( candidate. sidechain_public_key . 0 . clone ( ) ) ) ;
105- for key in candidate. keys . 0 . iter ( ) {
106- candidate_datum. add ( & PlutusData :: new_bytes ( key. bytes . clone ( ) ) ) ;
135+ fn candidates_to_plutus_data_v0 ( candidates : & [ PermissionedCandidateData ] ) -> PlutusData {
136+ let mut list = PlutusList :: new ( ) ;
137+ for candidate in candidates {
138+ let mut candidate_datum = PlutusList :: new ( ) ;
139+ candidate_datum. add ( & PlutusData :: new_bytes ( candidate. sidechain_public_key . 0 . clone ( ) ) ) ;
140+ for key in candidate. keys . 0 . iter ( ) {
141+ candidate_datum. add ( & PlutusData :: new_bytes ( key. bytes . clone ( ) ) ) ;
142+ }
143+ list. add ( & PlutusData :: new_list ( & candidate_datum) ) ;
144+ }
145+ let appendix = PlutusData :: new_list ( & list) ;
146+ VersionedGenericDatum {
147+ datum : PlutusData :: new_empty_constr_plutus_data ( & BigNum :: zero ( ) ) ,
148+ appendix,
149+ version : 0 ,
107150 }
108- list . add ( & PlutusData :: new_list ( & candidate_datum ) ) ;
151+ . into ( )
109152 }
110- let appendix = PlutusData :: new_list ( & list) ;
111- VersionedGenericDatum {
112- datum : PlutusData :: new_empty_constr_plutus_data ( & BigNum :: zero ( ) ) ,
113- appendix,
114- version : 0 ,
153+
154+ fn candidates_to_plutus_data_v1 ( candidates : & [ PermissionedCandidateData ] ) -> PlutusData {
155+ let mut list = PlutusList :: new ( ) ;
156+ for candidate in candidates {
157+ let mut candidate_datum = PlutusList :: new ( ) ;
158+ candidate_datum. add ( & PlutusData :: new_bytes ( candidate. sidechain_public_key . 0 . clone ( ) ) ) ;
159+ candidate_datum. add ( & candidate_keys_to_plutus ( & candidate. keys ) ) ;
160+ list. add ( & PlutusData :: new_list ( & candidate_datum) ) ;
161+ }
162+ VersionedGenericDatum {
163+ datum : PlutusData :: new_empty_constr_plutus_data ( & BigNum :: zero ( ) ) ,
164+ appendix : PlutusData :: new_list ( & list) ,
165+ version : 1 ,
166+ }
167+ . into ( )
168+ }
169+
170+ if candidates. iter ( ) . all ( |c| c. keys . has_only_aura_and_grandpa_keys ( ) ) {
171+ candidates_to_plutus_data_v0 ( candidates)
172+ } else {
173+ candidates_to_plutus_data_v1 ( candidates)
115174 }
116- . into ( )
117175}
118176
119177impl PermissionedCandidateDatums {
120178 /// Parses plutus data schema in accordance with V1 schema
121- fn decode_v1 ( data : & PlutusData ) -> Result < Self , String > {
179+ fn decode_v1_appendix ( data : & PlutusData ) -> Result < Self , String > {
122180 let permissioned_candidates = data
123181 . as_list ( )
124182 . and_then ( |list_datums| {
@@ -156,9 +214,10 @@ impl VersionedDatumWithLegacy for PermissionedCandidateDatums {
156214 appendix : & PlutusData ,
157215 ) -> Result < Self , String > {
158216 match version {
217+ // v0 appendix is the same as legacy format of whole plutus data
159218 0 => PermissionedCandidateDatums :: decode_legacy ( appendix)
160219 . map_err ( |msg| format ! ( "Cannot parse appendix: {msg}" ) ) ,
161- 1 => PermissionedCandidateDatums :: decode_v1 ( appendix)
220+ 1 => PermissionedCandidateDatums :: decode_v1_appendix ( appendix)
162221 . map_err ( |msg| format ! ( "Cannot parse appendix: {msg}" ) ) ,
163222 _ => Err ( format ! ( "Unknown version: {version}" ) ) ,
164223 }
@@ -184,7 +243,7 @@ fn decode_legacy_candidate_datum(datum: &PlutusData) -> Option<PermissionedCandi
184243fn decode_v1_candidate_datum ( datum : & PlutusData ) -> Option < PermissionedCandidateDatumV1 > {
185244 // The first element has Partner Chains key, second contains all other keys
186245 let outer_list = datum. as_list ( ) . filter ( |l| l. len ( ) == 2 ) ?;
187- let partner_chains_key = decode_candidate_key ( & outer_list. get ( 0 ) ) ? ;
246+ let partner_chains_key = SidechainPublicKey ( outer_list. get ( 0 ) . as_bytes ( ) ? ) ;
188247 let keys = decode_candidate_keys ( & outer_list. get ( 1 ) ) ?;
189248 Some ( PermissionedCandidateDatumV1 { partner_chains_key, keys } )
190249}
@@ -267,14 +326,14 @@ mod tests {
267326 { "constructor" : 0 , "fields" : [ ] } ,
268327 { "list" : [
269328 { "list" : [
270- { "list" : [ { " bytes": hex :: encode ( b"crch" ) } , { "bytes" : " cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"} ] } ,
329+ { "bytes" : " cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"} ,
271330 { "list" : [
272331 { "list" : [ { "bytes" : hex:: encode( b"aura" ) } , { "bytes" : "bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec" } ] } ,
273332 { "list" : [ { "bytes" : hex:: encode( b"gran" ) } , { "bytes" : "9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d" } ] }
274333 ] }
275334 ] } ,
276335 { "list" : [
277- { "list" : [ { " bytes": hex :: encode ( b"crch" ) } , { "bytes" : " 79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"} ] } ,
336+ { "bytes" : " 79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"} ,
278337 { "list" : [
279338 { "list" : [ { "bytes" : hex:: encode( b"aura" ) } , { "bytes" : "56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19" } ] } ,
280339 { "list" : [ { "bytes" : hex:: encode( b"gran" ) } , { "bytes" : "7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32" } ] }
@@ -287,7 +346,7 @@ mod tests {
287346 }
288347
289348 #[ test]
290- fn test_permissioned_candidates_to_plutus_data ( ) {
349+ fn permissioned_candidates_to_plutus_data_outputs_v0_for_aura_and_grandpa_keys ( ) {
291350 let expected_plutus_data = json_to_plutus_data ( v0_datum_json ( ) ) ;
292351
293352 let domain_data = vec ! [
@@ -331,6 +390,50 @@ mod tests {
331390 assert_eq ! ( permissioned_candidates_to_plutus_data( & domain_data) , expected_plutus_data)
332391 }
333392
393+ #[ test]
394+ fn permissioned_candidates_to_plutus_data_outputs_v1 ( ) {
395+ let domain_data = vec ! [
396+ PermissionedCandidateData {
397+ sidechain_public_key: SidechainPublicKey ( [ 1 ; 33 ] . to_vec( ) ) ,
398+ keys: CandidateKeys ( vec![
399+ CandidateKey { id: [ 2 ; 4 ] , bytes: [ 3 ; 32 ] . to_vec( ) } ,
400+ CandidateKey { id: [ 4 ; 4 ] , bytes: [ 5 ; 32 ] . to_vec( ) } ,
401+ ] ) ,
402+ } ,
403+ PermissionedCandidateData {
404+ sidechain_public_key: SidechainPublicKey ( [ 6 ; 33 ] . to_vec( ) ) ,
405+ keys: CandidateKeys ( vec![
406+ CandidateKey { id: [ 7 ; 4 ] , bytes: [ 8 ; 32 ] . to_vec( ) } ,
407+ CandidateKey { id: [ 9 ; 4 ] , bytes: [ 10u8 ; 32 ] . to_vec( ) } ,
408+ ] ) ,
409+ } ,
410+ ] ;
411+ let json = serde_json:: json!( {
412+ "list" : [
413+ { "constructor" : 0 , "fields" : [ ] } ,
414+ { "list" : [
415+ { "list" : [
416+ { "bytes" : "010101010101010101010101010101010101010101010101010101010101010101" } ,
417+ { "list" : [
418+ { "list" : [ { "bytes" : "02020202" } , { "bytes" : "0303030303030303030303030303030303030303030303030303030303030303" } ] } ,
419+ { "list" : [ { "bytes" : "04040404" } , { "bytes" : "0505050505050505050505050505050505050505050505050505050505050505" } ] }
420+ ] }
421+ ] } ,
422+ { "list" : [
423+ { "bytes" : "060606060606060606060606060606060606060606060606060606060606060606" } ,
424+ { "list" : [
425+ { "list" : [ { "bytes" : "07070707" } , { "bytes" : "0808080808080808080808080808080808080808080808080808080808080808" } ] } ,
426+ { "list" : [ { "bytes" : "09090909" } , { "bytes" : "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a" } ] }
427+ ] }
428+ ] }
429+ ] } ,
430+ { "int" : 1 }
431+ ]
432+ } ) ;
433+ let expected_plutus_data = json_to_plutus_data ( json) ;
434+ assert_eq ! ( permissioned_candidates_to_plutus_data( & domain_data) , expected_plutus_data)
435+ }
436+
334437 #[ test]
335438 fn valid_v0_permissioned_candidates ( ) {
336439 let plutus_data = json_to_plutus_data ( v0_datum_json ( ) ) ;
@@ -369,8 +472,7 @@ mod tests {
369472
370473 let expected_datum = PermissionedCandidateDatums :: V1 ( vec ! [
371474 PermissionedCandidateDatumV1 {
372- partner_chains_key: CandidateKey :: new(
373- CROSS_CHAIN_KEY_TYPE_ID ,
475+ partner_chains_key: SidechainPublicKey (
374476 hex!( "cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854" ) . into( ) ,
375477 ) ,
376478 keys: CandidateKeys ( vec![
@@ -387,8 +489,7 @@ mod tests {
387489 ] ) ,
388490 } ,
389491 PermissionedCandidateDatumV1 {
390- partner_chains_key: CandidateKey :: new(
391- CROSS_CHAIN_KEY_TYPE_ID ,
492+ partner_chains_key: SidechainPublicKey (
392493 hex!( "79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf" ) . into( ) ,
393494 ) ,
394495 keys: CandidateKeys ( vec![
0 commit comments