@@ -15,12 +15,17 @@ use ed25519_dalek::{PublicKey, Signature, Verifier};
1515use serde_json:: json;
1616use solana_sdk:: { pubkey:: Pubkey , transaction:: VersionedTransaction } ;
1717
18+ pub const MAX_SIGNED_MSG_BORSH_LEN : usize = SignedMsgOrderParamsDelegateMessage :: INIT_SPACE + 8 ;
19+ pub const MAX_SIGNED_MSG_HEX_LEN : usize = MAX_SIGNED_MSG_BORSH_LEN * 2 ;
20+
1821#[ derive( Clone , Debug , PartialEq ) ]
1922pub struct SignedOrderTypeWithLen {
2023 /// length of the signed order when borsh encoded
2124 pub signed_len : usize ,
2225 /// signed order message
2326 pub order : SignedOrderType ,
27+ /// Original message bytes for ed25519
28+ pub original_message : Vec < u8 > ,
2429}
2530
2631/// Deserialize hex-ified, borsh bytes as a `SignedOrderType`
@@ -46,20 +51,24 @@ where
4651 faster_hex:: hex_decode ( payload. as_bytes ( ) , & mut borsh_buf[ ..borsh_len] )
4752 . map_err ( serde:: de:: Error :: custom) ?;
4853
54+ let original_message = payload. as_bytes ( ) . to_vec ( ) ;
55+
4956 // this is basically the same as if we derived AnchorDeserialize on `SignedOrderType` _expect_ it does not
5057 // add a u8 to distinguish the enum
5158 if borsh_buf[ ..8 ] == SWIFT_DELEGATE_MSG_PREFIX {
5259 AnchorDeserialize :: deserialize ( & mut & borsh_buf[ 8 ..] )
5360 . map ( |o| SignedOrderTypeWithLen {
5461 signed_len : borsh_len,
5562 order : SignedOrderType :: Delegated ( o) ,
63+ original_message,
5664 } )
5765 . map_err ( serde:: de:: Error :: custom)
5866 } else {
5967 AnchorDeserialize :: deserialize ( & mut & borsh_buf[ 8 ..] )
6068 . map ( |o| SignedOrderTypeWithLen {
6169 signed_len : borsh_len,
6270 order : SignedOrderType :: Authority ( o) ,
71+ original_message,
6372 } )
6473 . map_err ( serde:: de:: Error :: custom)
6574 }
@@ -101,15 +110,8 @@ impl IncomingSignedMessage {
101110 PublicKey :: from_bytes ( self . taker_pubkey . as_array ( ) )
102111 } ?;
103112
104- // client hex encodes msg before signing so use that as comparison
105- // since we allow older clients with potentially shorter messages than the current IDL
106- // need to truncate the message to the size the client signed (exclude default padded bytes)
107- let msg_data = & self . order ( ) . to_borsh ( ) [ ..self . message . signed_len ] ;
108- let mut hex_bytes = vec ! [ 0 ; msg_data. len( ) * 2 ] ; // 2 hex bytes per msg byte
109- let _ = faster_hex:: hex_encode ( msg_data, & mut hex_bytes) . expect ( "hexified" ) ;
110-
111113 pubkey
112- . verify ( & hex_bytes , & self . signature )
114+ . verify ( & self . message . original_message , & self . signature )
113115 . context ( "Signature did not verify" )
114116 }
115117 pub fn verify_and_get_signed_message ( & self ) -> Result < & SignedOrderType > {
@@ -122,7 +124,9 @@ impl IncomingSignedMessage {
122124pub struct OrderMetadataAndMessage {
123125 pub signing_authority : Pubkey ,
124126 pub taker_authority : Pubkey ,
125- pub order_message : SignedOrderType ,
127+ #[ max_len( MAX_SIGNED_MSG_HEX_LEN ) ]
128+ pub order_message : Vec < u8 > ,
129+ pub deserialized_order_message : SignedOrderType ,
126130 pub order_signature : [ u8 ; 64 ] ,
127131 pub uuid : [ u8 ; 8 ] ,
128132 pub ts : u64 ,
@@ -156,16 +160,25 @@ impl OrderMetadataAndMessage {
156160 }
157161
158162 pub fn jsonify ( & self ) -> serde_json:: Value {
159- let taker_order_params = self . order_message . info ( & self . taker_authority ) . order_params ;
160- let signed_msg_borsh = self . order_message . to_borsh ( ) ;
163+ let taker_order_params = self
164+ . deserialized_order_message
165+ . info ( & self . taker_authority )
166+ . order_params ;
167+
168+ let order_message_str = match core:: str:: from_utf8 ( & self . order_message ) {
169+ Ok ( s) if s. as_bytes ( ) . iter ( ) . all ( u8:: is_ascii_hexdigit) && ( s. len ( ) % 2 == 0 ) => {
170+ s. to_string ( )
171+ }
172+ _ => faster_hex:: hex_string ( self . order_message . as_slice ( ) ) ,
173+ } ;
161174
162175 json ! ( {
163176 "market_type" : match taker_order_params. market_type {
164177 MarketType :: Perp => "perp" ,
165178 MarketType :: Spot => "spot" ,
166179 } ,
167180 "market_index" : taker_order_params. market_index,
168- "order_message" : faster_hex :: hex_string ( signed_msg_borsh . as_slice ( ) ) ,
181+ "order_message" : order_message_str ,
169182 "order_signature" : base64:: prelude:: BASE64_STANDARD . encode( self . order_signature) ,
170183 "taker_authority" : self . taker_authority. to_string( ) ,
171184 "signing_authority" : self . signing_authority. to_string( ) ,
@@ -521,7 +534,8 @@ mod tests {
521534 let encoded = OrderMetadataAndMessage {
522535 signing_authority : Pubkey :: new_unique ( ) ,
523536 taker_authority : Pubkey :: new_unique ( ) ,
524- order_message : SignedOrderType :: Authority ( Default :: default ( ) ) ,
537+ order_message : vec ! [ 0u8 ; 2 * ( SignedMsgOrderParamsDelegateMessage :: INIT_SPACE + 8 ) ] ,
538+ deserialized_order_message : SignedOrderType :: Authority ( Default :: default ( ) ) ,
525539 order_signature : [ 1u8 ; 64 ] ,
526540 ts : 55555 ,
527541 uuid : nanoid ! ( 8 ) . as_bytes ( ) . try_into ( ) . unwrap ( ) ,
@@ -531,7 +545,7 @@ mod tests {
531545 let order_metadata = OrderMetadataAndMessage :: decode ( & encoded) . unwrap ( ) ;
532546 dbg ! ( base64:: prelude:: BASE64_STANDARD . encode(
533547 & order_metadata
534- . order_message
548+ . deserialized_order_message
535549 . try_to_vec( )
536550 . unwrap( )
537551 . as_slice( )
@@ -560,13 +574,15 @@ mod tests {
560574 } ;
561575
562576 let signed_order_message = SignedOrderType :: Authority ( order_params) ;
577+ let hex_msg = faster_hex:: hex_string ( signed_order_message. to_borsh ( ) . as_slice ( ) ) ;
563578
564579 let order_metadata_json = OrderMetadataAndMessage {
565580 signing_authority,
566581 taker_authority,
582+ order_message : hex_msg. as_bytes ( ) . to_vec ( ) ,
567583 order_signature,
568584 uuid : order_params. uuid ,
569- order_message : signed_order_message. clone ( ) ,
585+ deserialized_order_message : signed_order_message. clone ( ) ,
570586 ts : 55555 ,
571587 will_sanitize : false ,
572588 }
@@ -585,10 +601,7 @@ mod tests {
585601 base64:: prelude:: BASE64_STANDARD . encode( order_signature) ,
586602 ) ;
587603
588- assert_eq ! (
589- order_metadata_json[ "order_message" ] ,
590- faster_hex:: hex_string( signed_order_message. to_borsh( ) . as_slice( ) ) ,
591- ) ;
604+ assert_eq ! ( order_metadata_json[ "order_message" ] , hex_msg, ) ;
592605
593606 assert_eq ! ( order_metadata_json[ "ts" ] , 55555 ) ;
594607
0 commit comments