@@ -103,24 +103,45 @@ impl Setup {
103
103
}
104
104
105
105
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 > {
106
136
// Instruction #0 will be ed25519 instruction;
107
137
// Instruction #1 will be our contract instruction.
108
138
let instruction_index = 1 ;
109
- // 8 bytes for Anchor header, 4 bytes for Vec length.
110
- let message_offset = 12 ;
111
139
let ed25519_args = dbg ! ( pyth_lazer_solana_contract:: Ed25519SignatureOffsets :: new(
112
140
message,
113
141
instruction_index,
114
142
message_offset,
115
143
) ) ;
116
144
117
- let treasury_starting_lamports = self
118
- . banks_client
119
- . get_account ( treasury)
120
- . await
121
- . unwrap ( )
122
- . unwrap ( )
123
- . lamports ;
124
145
let mut transaction_verify = Transaction :: new_with_payer (
125
146
& [
126
147
Instruction :: new_with_bytes (
@@ -151,17 +172,6 @@ impl Setup {
151
172
self . banks_client
152
173
. process_transaction ( transaction_verify)
153
174
. 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
- ) ;
165
175
}
166
176
}
167
177
@@ -206,6 +216,84 @@ async fn test_basic() {
206
216
setup. verify_message ( & message, treasury) . await ;
207
217
}
208
218
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
+
209
297
#[ tokio:: test]
210
298
async fn test_migrate_from_0_1_0 ( ) {
211
299
let mut program_test = program_test ( ) ;
0 commit comments