@@ -32,16 +32,15 @@ impl From<PermissionedCandidateDatumV1> for PermissionedCandidateData {
32
32
// with T: OpaqueKeys, this function will be re-implemented.
33
33
fn from ( value : PermissionedCandidateDatumV1 ) -> Self {
34
34
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 }
37
36
}
38
37
}
39
38
40
39
#[ derive( Clone , Debug , PartialEq ) ]
41
40
/// Datum representing a permissioned candidate with arbitrary set of keys
42
41
pub struct PermissionedCandidateDatumV1 {
43
42
/// Partner Chains key identifier and bytes
44
- pub partner_chains_key : CandidateKey ,
43
+ pub partner_chains_key : SidechainPublicKey ,
45
44
/// Represents arbitrary set of keys with 4 character identifier
46
45
pub keys : CandidateKeys ,
47
46
}
@@ -75,11 +74,12 @@ impl From<PermissionedCandidateDatums> for Vec<PermissionedCandidateData> {
75
74
}
76
75
77
76
/// 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.
79
79
/// Encoding:
80
80
/// ```ignore
81
81
/// VersionedGenericDatum:
82
- /// - datum: ()
82
+ /// - datum: Constr 0 []
83
83
/// - appendix:
84
84
/// [
85
85
/// [ candidates[0].sidechain_public_key
@@ -94,31 +94,89 @@ impl From<PermissionedCandidateDatums> for Vec<PermissionedCandidateData> {
94
94
/// // etc.
95
95
/// ]
96
96
/// - 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
97
130
/// ```
131
+
98
132
pub fn permissioned_candidates_to_plutus_data (
99
133
candidates : & [ PermissionedCandidateData ] ,
100
134
) -> 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 ,
107
150
}
108
- list . add ( & PlutusData :: new_list ( & candidate_datum ) ) ;
151
+ . into ( )
109
152
}
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)
115
174
}
116
- . into ( )
117
175
}
118
176
119
177
impl PermissionedCandidateDatums {
120
178
/// 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 > {
122
180
let permissioned_candidates = data
123
181
. as_list ( )
124
182
. and_then ( |list_datums| {
@@ -156,9 +214,10 @@ impl VersionedDatumWithLegacy for PermissionedCandidateDatums {
156
214
appendix : & PlutusData ,
157
215
) -> Result < Self , String > {
158
216
match version {
217
+ // v0 appendix is the same as legacy format of whole plutus data
159
218
0 => PermissionedCandidateDatums :: decode_legacy ( appendix)
160
219
. map_err ( |msg| format ! ( "Cannot parse appendix: {msg}" ) ) ,
161
- 1 => PermissionedCandidateDatums :: decode_v1 ( appendix)
220
+ 1 => PermissionedCandidateDatums :: decode_v1_appendix ( appendix)
162
221
. map_err ( |msg| format ! ( "Cannot parse appendix: {msg}" ) ) ,
163
222
_ => Err ( format ! ( "Unknown version: {version}" ) ) ,
164
223
}
@@ -184,7 +243,7 @@ fn decode_legacy_candidate_datum(datum: &PlutusData) -> Option<PermissionedCandi
184
243
fn decode_v1_candidate_datum ( datum : & PlutusData ) -> Option < PermissionedCandidateDatumV1 > {
185
244
// The first element has Partner Chains key, second contains all other keys
186
245
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 ( ) ? ) ;
188
247
let keys = decode_candidate_keys ( & outer_list. get ( 1 ) ) ?;
189
248
Some ( PermissionedCandidateDatumV1 { partner_chains_key, keys } )
190
249
}
@@ -267,14 +326,14 @@ mod tests {
267
326
{ "constructor" : 0 , "fields" : [ ] } ,
268
327
{ "list" : [
269
328
{ "list" : [
270
- { "list" : [ { " bytes": hex :: encode ( b"crch" ) } , { "bytes" : " cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"} ] } ,
329
+ { "bytes" : " cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854"} ,
271
330
{ "list" : [
272
331
{ "list" : [ { "bytes" : hex:: encode( b"aura" ) } , { "bytes" : "bf20afa1c1a72af3341fa7a447e3f9eada9f3d054a7408fb9e49ad4d6e6559ec" } ] } ,
273
332
{ "list" : [ { "bytes" : hex:: encode( b"gran" ) } , { "bytes" : "9042a40b0b1baa9adcead024432a923eac706be5e1a89d7f2f2d58bfa8f3c26d" } ] }
274
333
] }
275
334
] } ,
276
335
{ "list" : [
277
- { "list" : [ { " bytes": hex :: encode ( b"crch" ) } , { "bytes" : " 79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"} ] } ,
336
+ { "bytes" : " 79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf"} ,
278
337
{ "list" : [
279
338
{ "list" : [ { "bytes" : hex:: encode( b"aura" ) } , { "bytes" : "56d1da82e56e4cb35b13de25f69a3e9db917f3e13d6f786321f4b0a9dc153b19" } ] } ,
280
339
{ "list" : [ { "bytes" : hex:: encode( b"gran" ) } , { "bytes" : "7392f3ea668aa2be7997d82c07bcfbec3ee4a9a4e01e3216d92b8f0d0a086c32" } ] }
@@ -287,7 +346,7 @@ mod tests {
287
346
}
288
347
289
348
#[ test]
290
- fn test_permissioned_candidates_to_plutus_data ( ) {
349
+ fn permissioned_candidates_to_plutus_data_outputs_v0_for_aura_and_grandpa_keys ( ) {
291
350
let expected_plutus_data = json_to_plutus_data ( v0_datum_json ( ) ) ;
292
351
293
352
let domain_data = vec ! [
@@ -331,6 +390,50 @@ mod tests {
331
390
assert_eq ! ( permissioned_candidates_to_plutus_data( & domain_data) , expected_plutus_data)
332
391
}
333
392
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
+
334
437
#[ test]
335
438
fn valid_v0_permissioned_candidates ( ) {
336
439
let plutus_data = json_to_plutus_data ( v0_datum_json ( ) ) ;
@@ -369,8 +472,7 @@ mod tests {
369
472
370
473
let expected_datum = PermissionedCandidateDatums :: V1 ( vec ! [
371
474
PermissionedCandidateDatumV1 {
372
- partner_chains_key: CandidateKey :: new(
373
- CROSS_CHAIN_KEY_TYPE_ID ,
475
+ partner_chains_key: SidechainPublicKey (
374
476
hex!( "cb6df9de1efca7a3998a8ead4e02159d5fa99c3e0d4fd6432667390bb4726854" ) . into( ) ,
375
477
) ,
376
478
keys: CandidateKeys ( vec![
@@ -387,8 +489,7 @@ mod tests {
387
489
] ) ,
388
490
} ,
389
491
PermissionedCandidateDatumV1 {
390
- partner_chains_key: CandidateKey :: new(
391
- CROSS_CHAIN_KEY_TYPE_ID ,
492
+ partner_chains_key: SidechainPublicKey (
392
493
hex!( "79c3b7fc0b7697b9414cb87adcb37317d1cab32818ae18c0e97ad76395d1fdcf" ) . into( ) ,
393
494
) ,
394
495
keys: CandidateKeys ( vec![
0 commit comments