1
1
use axelar_wasm_std:: hash:: Hash ;
2
2
use axelar_wasm_std:: FnExt ;
3
+ use cosmwasm_std:: HexBinary ;
3
4
use error_stack:: { Result , ResultExt } ;
5
+ use multisig:: msg:: SignerWithSig ;
4
6
use multisig:: verifier_set:: VerifierSet ;
5
7
use sha3:: { Digest , Keccak256 } ;
6
- use stellar:: { Message , Messages , WeightedSigners } ;
8
+ use stellar:: { Message , Messages , Proof , WeightedSigners } ;
9
+ use stellar_xdr:: curr:: { Limits , ScVal , WriteXdr } ;
7
10
8
11
use crate :: error:: ContractError ;
9
12
use crate :: payload:: Payload ;
@@ -42,15 +45,49 @@ pub fn payload_digest(
42
45
Ok ( Keccak256 :: digest ( unsigned) . into ( ) )
43
46
}
44
47
48
+ /// `encode_execute_data` returns the XDR encoded external gateway function call args.
49
+ /// The relayer will use this data to submit the payload to the contract.
50
+ pub fn encode_execute_data (
51
+ verifier_set : & VerifierSet ,
52
+ signatures : Vec < SignerWithSig > ,
53
+ payload : & Payload ,
54
+ ) -> Result < HexBinary , ContractError > {
55
+ let payload = match payload {
56
+ Payload :: Messages ( messages) => ScVal :: try_from (
57
+ messages
58
+ . iter ( )
59
+ . map ( Message :: try_from)
60
+ . collect :: < Result < Vec < _ > , _ > > ( )
61
+ . change_context ( ContractError :: InvalidMessage ) ?
62
+ . then ( Messages :: from) ,
63
+ ) ,
64
+ Payload :: VerifierSet ( verifier_set) => ScVal :: try_from (
65
+ WeightedSigners :: try_from ( verifier_set)
66
+ . change_context ( ContractError :: InvalidVerifierSet ) ?,
67
+ ) ,
68
+ }
69
+ . change_context ( ContractError :: SerializeData ) ?;
70
+
71
+ let proof =
72
+ Proof :: try_from ( ( verifier_set. clone ( ) , signatures) ) . change_context ( ContractError :: Proof ) ?;
73
+
74
+ let execute_data = ScVal :: try_from ( ( payload, proof) )
75
+ . expect ( "must convert tuple of size 2 to ScVec" )
76
+ . to_xdr ( Limits :: none ( ) )
77
+ . change_context ( ContractError :: SerializeData ) ?;
78
+
79
+ Ok ( execute_data. as_slice ( ) . into ( ) )
80
+ }
45
81
#[ cfg( test) ]
46
82
mod tests {
47
83
use cosmwasm_std:: { Addr , HexBinary , Uint128 } ;
48
- use multisig:: key:: KeyType ;
49
- use multisig:: msg:: Signer ;
84
+ use multisig:: key:: KeyType :: Ed25519 ;
85
+ use multisig:: key:: Signature ;
86
+ use multisig:: msg:: { Signer , SignerWithSig } ;
50
87
use multisig:: verifier_set:: VerifierSet ;
51
88
use router_api:: { CrossChainId , Message } ;
52
89
53
- use crate :: encoding:: stellar_xdr:: payload_digest;
90
+ use crate :: encoding:: stellar_xdr:: { encode_execute_data , payload_digest} ;
54
91
use crate :: payload:: Payload ;
55
92
56
93
#[ test]
@@ -87,7 +124,7 @@ mod tests {
87
124
6u128 ,
88
125
) ,
89
126
] ;
90
- let verifier_set = gen_veifier_set ( signers_data, 22 , 2024 ) ;
127
+ let verifier_set = gen_verifier_set ( signers_data, 22 , 2024 ) ;
91
128
92
129
let payload = Payload :: Messages ( vec ! [ Message {
93
130
cc_id: CrossChainId {
@@ -120,7 +157,7 @@ mod tests {
120
157
121
158
#[ test]
122
159
fn stellar_verifier_set_payload_digest ( ) {
123
- let verifier_set = gen_veifier_set (
160
+ let verifier_set = gen_verifier_set (
124
161
vec ! [ (
125
162
"addr_1" ,
126
163
"bf95c447eb2e694974ee2cf5f17e7165bc884a0cb676bb4de50c604bb7a6ea77" ,
@@ -156,7 +193,7 @@ mod tests {
156
193
7u128 ,
157
194
) ,
158
195
] ;
159
- let payload = Payload :: VerifierSet ( gen_veifier_set ( signers_data, 27 , 2024 ) ) ;
196
+ let payload = Payload :: VerifierSet ( gen_verifier_set ( signers_data, 27 , 2024 ) ) ;
160
197
let domain_separator: [ u8 ; 32 ] =
161
198
HexBinary :: from_hex ( "6773bd037510492f863cba62a0f3c55ac846883f33cae7266aff8be5eb9681e8" )
162
199
. unwrap ( )
@@ -168,7 +205,130 @@ mod tests {
168
205
) ) ;
169
206
}
170
207
171
- fn gen_veifier_set (
208
+ #[ test]
209
+ fn stellar_approve_messages_execute_data ( ) {
210
+ let signers_data = vec ! [
211
+ (
212
+ "addr_1" ,
213
+ "12f7d9a9463212335914b39ee90bfa2045f90b64c1f2d7b58ed335282abac4a4" ,
214
+ 8u128 ,
215
+ "b5b3b0749aa585f866d802e32ca4a6356f82eb52e2a1b4797cbaa30f3d755462f2eb995c70d9099e436b8a48498e4d613ff2d3ca7618973a36c2fde17493180f" ,
216
+ ) ,
217
+ (
218
+ "addr_2" ,
219
+ "4c3863e4b0252a8674c1c6ad70b3ca3002b400b49ddfae5583b21907e65c5dd8" ,
220
+ 1u128 ,
221
+ "cb8a1b98ec7678d5eb965d47c449b2b8396d170e53ad7b5f65a7c0fdf2aebe206b65be7cb2e81c7ddd8924acb2ffc2d463b678993227fdfbfc3ef03a8ffa030c" ,
222
+ ) ,
223
+ (
224
+ "addr_3" ,
225
+ "c35aa94d2038f258ecb1bb28fbc8a83ab79d2dc0a7223fd528a8f52a14c03292" ,
226
+ 7u128 ,
227
+ "28e2c8accfa1c2db93349c6d3f783004d6a92cdbf322b92b3555315999e0eaf5d8bdf9deb58d798168a880972e81b8513dcb942de44862317d501cf7445c660a"
228
+ ) ,
229
+
230
+ ] ;
231
+
232
+ let verifier_set = gen_verifier_set (
233
+ signers_data
234
+ . iter ( )
235
+ . map ( |( t1, t2, t3, _) | ( * t1, * t2, * t3) )
236
+ . collect ( ) ,
237
+ 10 ,
238
+ 2024 ,
239
+ ) ;
240
+
241
+ let signer_with_sig = gen_signers_with_sig ( signers_data) ;
242
+
243
+ let payload = Payload :: Messages ( vec ! [ Message {
244
+ cc_id: CrossChainId {
245
+ source_chain: "source" . parse( ) . unwrap( ) ,
246
+ message_id: "test" . parse( ) . unwrap( ) ,
247
+ } ,
248
+ source_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M"
249
+ . parse( )
250
+ . unwrap( ) ,
251
+ destination_chain: "stellar" . parse( ) . unwrap( ) ,
252
+ destination_address: "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4"
253
+ . parse( )
254
+ . unwrap( ) ,
255
+ payload_hash: HexBinary :: from_hex(
256
+ "595c9108df17d1cc43e8268ec1516064299c1388bcc86fdd566bcdf400a0a1ed" ,
257
+ )
258
+ . unwrap( )
259
+ . to_array( )
260
+ . unwrap( ) ,
261
+ } ] ) ;
262
+
263
+ goldie:: assert!(
264
+ encode_execute_data( & verifier_set, signer_with_sig, & payload)
265
+ . unwrap( )
266
+ . to_hex( )
267
+ ) ;
268
+ }
269
+
270
+ #[ test]
271
+ fn stellar_rotate_signers_execute_data ( ) {
272
+ let signers_data = vec ! [
273
+ (
274
+ "addr_1" ,
275
+ "77dd4768dda195f8080fe970be8fec5fee9cea781718158ce19d4a331442fd57" ,
276
+ 2u128 ,
277
+ "91db8ad94ab379ee9021caeb3ee852582d09d06801213256cbd2937f2ad8182f518fde7a7f8c801adde7161e05cbbb9841ac0bf3290831570a54c6ae3d089703" ,
278
+ ) ,
279
+ ] ;
280
+
281
+ let verifier_set = gen_verifier_set (
282
+ signers_data
283
+ . iter ( )
284
+ . map ( |( t1, t2, t3, _) | ( * t1, * t2, * t3) )
285
+ . collect ( ) ,
286
+ 1 ,
287
+ 2024 ,
288
+ ) ;
289
+
290
+ let signer_with_sig = gen_signers_with_sig ( signers_data) ;
291
+
292
+ let payload = Payload :: VerifierSet ( gen_verifier_set (
293
+ vec ! [
294
+ (
295
+ "addr_1" ,
296
+ "358a2305fc783b6072049ee6f5f76fb14c3a14d7c01e36d9ef502661bf46a011" ,
297
+ 9u128 ,
298
+ ) ,
299
+ (
300
+ "addr_2" ,
301
+ "3b1caf530189a9a65ae347b18cb8bf88729ba90d2aeaf7f185b600400ab49891" ,
302
+ 1u128 ,
303
+ ) ,
304
+ (
305
+ "addr_3" ,
306
+ "531616448afd45c0e3e053622cbccb65d8fc99cd2f02636d728739811e72eafb" ,
307
+ 3u128 ,
308
+ ) ,
309
+ (
310
+ "addr_4" ,
311
+ "5e4c8ec6569774adf69cb6e2bc4ef556c2fc6b412c85d6a5e0b18d54b069e594" ,
312
+ 7u128 ,
313
+ ) ,
314
+ (
315
+ "addr_5" ,
316
+ "8097528d987899f887c08c23a928dfe6fe9550010d19c7be0b46b5d0596997cc" ,
317
+ 3u128 ,
318
+ ) ,
319
+ ] ,
320
+ 17 ,
321
+ 2024 ,
322
+ ) ) ;
323
+
324
+ goldie:: assert!(
325
+ encode_execute_data( & verifier_set, signer_with_sig, & payload)
326
+ . unwrap( )
327
+ . to_hex( )
328
+ ) ;
329
+ }
330
+
331
+ fn gen_verifier_set (
172
332
signers_data : Vec < ( & str , & str , u128 ) > ,
173
333
threshold : u128 ,
174
334
created_at : u64 ,
@@ -181,7 +341,7 @@ mod tests {
181
341
addr. to_string ( ) ,
182
342
Signer {
183
343
address : Addr :: unchecked ( addr) ,
184
- pub_key : ( KeyType :: Ed25519 , HexBinary :: from_hex ( pub_key) . unwrap ( ) )
344
+ pub_key : ( Ed25519 , HexBinary :: from_hex ( pub_key) . unwrap ( ) )
185
345
. try_into ( )
186
346
. unwrap ( ) ,
187
347
weight : Uint128 :: from ( weight) ,
@@ -193,4 +353,21 @@ mod tests {
193
353
created_at,
194
354
}
195
355
}
356
+ fn gen_signers_with_sig ( signers_data : Vec < ( & str , & str , u128 , & str ) > ) -> Vec < SignerWithSig > {
357
+ signers_data
358
+ . into_iter ( )
359
+ . map ( |( addr, pub_key, weight, sig) | {
360
+ Signer {
361
+ address : Addr :: unchecked ( addr) ,
362
+ pub_key : ( Ed25519 , HexBinary :: from_hex ( pub_key) . unwrap ( ) )
363
+ . try_into ( )
364
+ . unwrap ( ) ,
365
+ weight : Uint128 :: from ( weight) ,
366
+ }
367
+ . with_sig (
368
+ Signature :: try_from ( ( Ed25519 , HexBinary :: from_hex ( sig) . unwrap ( ) ) ) . unwrap ( ) ,
369
+ )
370
+ } )
371
+ . collect :: < Vec < _ > > ( )
372
+ }
196
373
}
0 commit comments