@@ -103,24 +103,45 @@ impl Setup {
103103 }
104104
105105 async fn verify_message ( & mut self , message : & [ u8 ] , treasury : Pubkey ) {
106+ let treasury_starting_lamports = self
107+ . banks_client
108+ . get_account ( treasury)
109+ . await
110+ . unwrap ( )
111+ . unwrap ( )
112+ . lamports ;
113+
114+ // 8 bytes for Anchor header, 4 bytes for Vec length.
115+ self . verify_message_with_offset ( message, treasury, 12 )
116+ . await
117+ . unwrap ( ) ;
118+
119+ assert_eq ! (
120+ self . banks_client
121+ . get_account( treasury)
122+ . await
123+ . unwrap( )
124+ . unwrap( )
125+ . lamports,
126+ treasury_starting_lamports + 1 ,
127+ ) ;
128+ }
129+
130+ async fn verify_message_with_offset (
131+ & mut self ,
132+ message : & [ u8 ] ,
133+ treasury : Pubkey ,
134+ message_offset : u16 ,
135+ ) -> Result < ( ) , BanksClientError > {
106136 // Instruction #0 will be ed25519 instruction;
107137 // Instruction #1 will be our contract instruction.
108138 let instruction_index = 1 ;
109- // 8 bytes for Anchor header, 4 bytes for Vec length.
110- let message_offset = 12 ;
111139 let ed25519_args = dbg ! ( pyth_lazer_solana_contract:: Ed25519SignatureOffsets :: new(
112140 message,
113141 instruction_index,
114142 message_offset,
115143 ) ) ;
116144
117- let treasury_starting_lamports = self
118- . banks_client
119- . get_account ( treasury)
120- . await
121- . unwrap ( )
122- . unwrap ( )
123- . lamports ;
124145 let mut transaction_verify = Transaction :: new_with_payer (
125146 & [
126147 Instruction :: new_with_bytes (
@@ -151,17 +172,6 @@ impl Setup {
151172 self . banks_client
152173 . process_transaction ( transaction_verify)
153174 . await
154- . unwrap ( ) ;
155-
156- assert_eq ! (
157- self . banks_client
158- . get_account( treasury)
159- . await
160- . unwrap( )
161- . unwrap( )
162- . lamports,
163- treasury_starting_lamports + 1 ,
164- ) ;
165175 }
166176}
167177
@@ -206,6 +216,84 @@ async fn test_basic() {
206216 setup. verify_message ( & message, treasury) . await ;
207217}
208218
219+ #[ tokio:: test]
220+ async fn test_rejects_wrong_offset ( ) {
221+ let mut setup = Setup :: new ( ) . await ;
222+ let treasury = setup. create_treasury ( ) . await ;
223+
224+ let mut transaction_init_contract = Transaction :: new_with_payer (
225+ & [ Instruction :: new_with_bytes (
226+ pyth_lazer_solana_contract:: ID ,
227+ & pyth_lazer_solana_contract:: instruction:: Initialize {
228+ top_authority : setup. payer . pubkey ( ) ,
229+ treasury,
230+ }
231+ . data ( ) ,
232+ vec ! [
233+ AccountMeta :: new( setup. payer. pubkey( ) , true ) ,
234+ AccountMeta :: new( pyth_lazer_solana_contract:: STORAGE_ID , false ) ,
235+ AccountMeta :: new_readonly( system_program:: ID , false ) ,
236+ ] ,
237+ ) ] ,
238+ Some ( & setup. payer . pubkey ( ) ) ,
239+ ) ;
240+ transaction_init_contract. sign ( & [ & setup. payer ] , setup. recent_blockhash ) ;
241+ setup
242+ . banks_client
243+ . process_transaction ( transaction_init_contract)
244+ . await
245+ . unwrap ( ) ;
246+
247+ let verifying_key =
248+ hex:: decode ( "74313a6525edf99936aa1477e94c72bc5cc617b21745f5f03296f3154461f214" ) . unwrap ( ) ;
249+ let verifying_key_2 =
250+ hex:: decode ( "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ) . unwrap ( ) ;
251+ let message = hex:: decode (
252+ [
253+ // --- First copy of the message (this data is returned by the Lazer contract)
254+
255+ // SOLANA_FORMAT_MAGIC_LE
256+ "b9011a82" ,
257+ // Signature
258+ "e5cddee2c1bd364c8c57e1c98a6a28d194afcad410ff412226c8b2ae931ff59a57147cb47c7307afc2a0a1abec4dd7e835a5b7113cf5aeac13a745c6bed6c600" ,
259+ // Pubkey
260+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" ,
261+ // Payload length (could be adjusted)
262+ "1c00" ,
263+ // Payload
264+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" ,
265+
266+ // --- Second copy of the message (this data is used by the ed25519 program)
267+
268+ // Unused, was SOLANA_FORMAT_MAGIC_LE, could be removed, left it for slightly easier offset adjustments
269+ "AABBCCDD" ,
270+ // Signature
271+ "e5cddee2c1bd364c8c57e1c98a6a28d194afcad410ff412226c8b2ae931ff59a57147cb47c7307afc2a0a1abec4dd7e835a5b7113cf5aeac13a745c6bed6c600" ,
272+ // Pubkey
273+ "74313a6525edf99936aa1477e94c72bc5cc617b21745f5f03296f3154461f214" ,
274+ // Payload length
275+ "1c00" ,
276+ // Payload
277+ "75d3c7931c9773f30a240600010102000000010000e1f50500000000"
278+ ] . concat ( )
279+ )
280+ . unwrap ( ) ;
281+
282+ setup. set_trusted ( verifying_key. try_into ( ) . unwrap ( ) ) . await ;
283+ setup. set_trusted ( verifying_key_2. try_into ( ) . unwrap ( ) ) . await ;
284+ let err = setup
285+ . verify_message_with_offset ( & message, treasury, 12 + 130 )
286+ . await
287+ . unwrap_err ( ) ;
288+ assert ! ( matches!(
289+ err,
290+ BanksClientError :: TransactionError ( TransactionError :: InstructionError (
291+ 1 ,
292+ InstructionError :: InvalidInstructionData
293+ ) )
294+ ) ) ;
295+ }
296+
209297#[ tokio:: test]
210298async fn test_migrate_from_0_1_0 ( ) {
211299 let mut program_test = program_test ( ) ;
0 commit comments