@@ -14,6 +14,9 @@ use solana_program::program_memory::sol_memcmp;
1414use solana_program:: sysvar;
1515use std:: convert:: TryInto ;
1616
17+ #[ cfg( test) ]
18+ mod tests;
19+
1720const ED25519_PROGRAM_INPUT_HEADER_LEN : usize = 2 ;
1821
1922const SIGNATURE_LEN : u16 = 64 ;
@@ -45,6 +48,7 @@ pub struct Ed25519SignatureOffsets {
4548 pub message_instruction_index : u16 ,
4649}
4750
51+ #[ derive( Debug ) ]
4852pub struct VerifiedMessage {
4953 pub signed_msg_order_params : OrderParams ,
5054 pub sub_account_id : Option < u16 > ,
@@ -53,13 +57,77 @@ pub struct VerifiedMessage {
5357 pub uuid : [ u8 ; 8 ] ,
5458 pub take_profit_order_params : Option < SignedMsgTriggerOrderParams > ,
5559 pub stop_loss_order_params : Option < SignedMsgTriggerOrderParams > ,
60+ pub max_margin_ratio : Option < u16 > ,
5661 pub signature : [ u8 ; 64 ] ,
5762}
5863
5964fn slice_eq ( a : & [ u8 ] , b : & [ u8 ] ) -> bool {
6065 a. len ( ) == b. len ( ) && sol_memcmp ( a, b, a. len ( ) ) == 0
6166}
6267
68+ pub fn deserialize_into_verified_message (
69+ payload : Vec < u8 > ,
70+ signature : & [ u8 ; 64 ] ,
71+ is_delegate_signer : bool ,
72+ ) -> Result < VerifiedMessage > {
73+ if is_delegate_signer {
74+ if payload. len ( ) < 8 {
75+ return Err ( SignatureVerificationError :: InvalidMessageDataSize . into ( ) ) ;
76+ }
77+ let min_len: usize = std:: mem:: size_of :: < SignedMsgOrderParamsDelegateMessage > ( ) ;
78+ let mut owned = payload;
79+ if owned. len ( ) < min_len {
80+ owned. resize ( min_len, 0 ) ;
81+ }
82+ let deserialized = SignedMsgOrderParamsDelegateMessage :: deserialize (
83+ & mut & owned[ 8 ..] , // 8 byte manual discriminator
84+ )
85+ . map_err ( |_| {
86+ msg ! ( "Invalid message encoding for is_delegate_signer = true" ) ;
87+ SignatureVerificationError :: InvalidMessageDataSize
88+ } ) ?;
89+
90+ return Ok ( VerifiedMessage {
91+ signed_msg_order_params : deserialized. signed_msg_order_params ,
92+ sub_account_id : None ,
93+ delegate_signed_taker_pubkey : Some ( deserialized. taker_pubkey ) ,
94+ slot : deserialized. slot ,
95+ uuid : deserialized. uuid ,
96+ take_profit_order_params : deserialized. take_profit_order_params ,
97+ stop_loss_order_params : deserialized. stop_loss_order_params ,
98+ max_margin_ratio : deserialized. max_margin_ratio ,
99+ signature : * signature,
100+ } ) ;
101+ } else {
102+ if payload. len ( ) < 8 {
103+ return Err ( SignatureVerificationError :: InvalidMessageDataSize . into ( ) ) ;
104+ }
105+ let min_len: usize = std:: mem:: size_of :: < SignedMsgOrderParamsMessage > ( ) ;
106+ let mut owned = payload;
107+ if owned. len ( ) < min_len {
108+ owned. resize ( min_len, 0 ) ;
109+ }
110+ let deserialized = SignedMsgOrderParamsMessage :: deserialize (
111+ & mut & owned[ 8 ..] , // 8 byte manual discriminator
112+ )
113+ . map_err ( |_| {
114+ msg ! ( "Invalid delegate message encoding for with is_delegate_signer = false" ) ;
115+ SignatureVerificationError :: InvalidMessageDataSize
116+ } ) ?;
117+ return Ok ( VerifiedMessage {
118+ signed_msg_order_params : deserialized. signed_msg_order_params ,
119+ sub_account_id : Some ( deserialized. sub_account_id ) ,
120+ delegate_signed_taker_pubkey : None ,
121+ slot : deserialized. slot ,
122+ uuid : deserialized. uuid ,
123+ take_profit_order_params : deserialized. take_profit_order_params ,
124+ stop_loss_order_params : deserialized. stop_loss_order_params ,
125+ max_margin_ratio : deserialized. max_margin_ratio ,
126+ signature : * signature,
127+ } ) ;
128+ }
129+ }
130+
63131/// Check Ed25519Program instruction data verifies the given msg
64132///
65133/// `ix` an Ed25519Program instruction [see](https://github.com/solana-labs/solana/blob/master/sdk/src/ed25519_instruction.rs))
@@ -232,45 +300,7 @@ pub fn verify_and_decode_ed25519_msg(
232300 let payload =
233301 hex:: decode ( payload) . map_err ( |_| SignatureVerificationError :: InvalidMessageHex ) ?;
234302
235- if is_delegate_signer {
236- let deserialized = SignedMsgOrderParamsDelegateMessage :: deserialize (
237- & mut & payload[ 8 ..] , // 8 byte manual discriminator
238- )
239- . map_err ( |_| {
240- msg ! ( "Invalid message encoding for is_delegate_signer = true" ) ;
241- SignatureVerificationError :: InvalidMessageDataSize
242- } ) ?;
243-
244- return Ok ( VerifiedMessage {
245- signed_msg_order_params : deserialized. signed_msg_order_params ,
246- sub_account_id : None ,
247- delegate_signed_taker_pubkey : Some ( deserialized. taker_pubkey ) ,
248- slot : deserialized. slot ,
249- uuid : deserialized. uuid ,
250- take_profit_order_params : deserialized. take_profit_order_params ,
251- stop_loss_order_params : deserialized. stop_loss_order_params ,
252- signature : * signature,
253- } ) ;
254- } else {
255- let deserialized = SignedMsgOrderParamsMessage :: deserialize (
256- & mut & payload[ 8 ..] , // 8 byte manual discriminator
257- )
258- . map_err ( |_| {
259- msg ! ( "Invalid delegate message encoding for with is_delegate_signer = false" ) ;
260- SignatureVerificationError :: InvalidMessageDataSize
261- } ) ?;
262-
263- return Ok ( VerifiedMessage {
264- signed_msg_order_params : deserialized. signed_msg_order_params ,
265- sub_account_id : Some ( deserialized. sub_account_id ) ,
266- delegate_signed_taker_pubkey : None ,
267- slot : deserialized. slot ,
268- uuid : deserialized. uuid ,
269- take_profit_order_params : deserialized. take_profit_order_params ,
270- stop_loss_order_params : deserialized. stop_loss_order_params ,
271- signature : * signature,
272- } ) ;
273- }
303+ deserialize_into_verified_message ( payload, signature, is_delegate_signer)
274304}
275305
276306#[ error_code]
0 commit comments