1
1
use {
2
2
anchor_lang:: { prelude:: AccountMeta , InstructionData } ,
3
- pyth_lazer_solana_contract:: ed25519_program_args,
3
+ pyth_lazer_solana_contract:: { ed25519_program_args, ANCHOR_DISCRIMINATOR_BYTES } ,
4
4
solana_program_test:: { BanksClient , ProgramTest } ,
5
5
solana_sdk:: {
6
- ed25519_program, hash:: Hash , instruction:: Instruction , pubkey:: Pubkey , signature:: Keypair ,
7
- signer:: Signer , system_instruction, system_program, system_transaction, sysvar,
6
+ account:: Account ,
7
+ ed25519_program,
8
+ hash:: Hash ,
9
+ instruction:: Instruction ,
10
+ pubkey:: { Pubkey , PUBKEY_BYTES } ,
11
+ signature:: Keypair ,
12
+ signer:: Signer ,
13
+ system_instruction, system_program, system_transaction, sysvar,
8
14
transaction:: Transaction ,
9
15
} ,
10
16
std:: env,
11
17
} ;
12
18
19
+ fn program_test ( ) -> ProgramTest {
20
+ if env:: var ( "SBF_OUT_DIR" ) . is_err ( ) {
21
+ env:: set_var (
22
+ "SBF_OUT_DIR" ,
23
+ format ! (
24
+ "{}/../../../../target/sbf-solana-solana/release" ,
25
+ env:: var( "CARGO_MANIFEST_DIR" ) . unwrap( )
26
+ ) ,
27
+ ) ;
28
+ }
29
+ println ! ( "if add_program fails, run `cargo build-sbf` first." ) ;
30
+ ProgramTest :: new (
31
+ "pyth_lazer_solana_contract" ,
32
+ pyth_lazer_solana_contract:: ID ,
33
+ None ,
34
+ )
35
+ }
36
+
13
37
struct Setup {
14
38
banks_client : BanksClient ,
15
39
payer : Keypair ,
16
40
recent_blockhash : Hash ,
17
41
}
18
42
19
43
impl Setup {
20
- async fn new ( ) -> Self {
21
- if env:: var ( "SBF_OUT_DIR" ) . is_err ( ) {
22
- env:: set_var (
23
- "SBF_OUT_DIR" ,
24
- format ! (
25
- "{}/../../../../target/sbf-solana-solana/release" ,
26
- env:: var( "CARGO_MANIFEST_DIR" ) . unwrap( )
27
- ) ,
28
- ) ;
29
- }
30
- println ! ( "if add_program fails, run `cargo build-sbf` first." ) ;
31
- let program_test = ProgramTest :: new (
32
- "pyth_lazer_solana_contract" ,
33
- pyth_lazer_solana_contract:: ID ,
34
- None ,
35
- ) ;
44
+ async fn with_program_test ( program_test : ProgramTest ) -> Self {
36
45
let ( banks_client, payer, recent_blockhash) = program_test. start ( ) . await ;
37
46
Self {
38
47
banks_client,
@@ -41,6 +50,10 @@ impl Setup {
41
50
}
42
51
}
43
52
53
+ async fn new ( ) -> Self {
54
+ Self :: with_program_test ( program_test ( ) ) . await
55
+ }
56
+
44
57
async fn create_treasury ( & mut self ) -> Pubkey {
45
58
let treasury =
46
59
Pubkey :: create_with_seed ( & self . payer . pubkey ( ) , "treasury" , & system_program:: ID )
@@ -154,14 +167,14 @@ impl Setup {
154
167
}
155
168
156
169
#[ tokio:: test]
157
- async fn test_with_init_v2 ( ) {
170
+ async fn test_basic ( ) {
158
171
let mut setup = Setup :: new ( ) . await ;
159
172
let treasury = setup. create_treasury ( ) . await ;
160
173
161
174
let mut transaction_init_contract = Transaction :: new_with_payer (
162
175
& [ Instruction :: new_with_bytes (
163
176
pyth_lazer_solana_contract:: ID ,
164
- & pyth_lazer_solana_contract:: instruction:: InitializeV2 {
177
+ & pyth_lazer_solana_contract:: instruction:: Initialize {
165
178
top_authority : setup. payer . pubkey ( ) ,
166
179
treasury,
167
180
}
@@ -195,32 +208,33 @@ async fn test_with_init_v2() {
195
208
}
196
209
197
210
#[ tokio:: test]
198
- async fn test_with_init_v1_and_migrate ( ) {
199
- let mut setup = Setup :: new ( ) . await ;
200
- let treasury = setup. create_treasury ( ) . await ;
201
-
202
- let mut transaction_init_contract = Transaction :: new_with_payer (
203
- & [ Instruction :: new_with_bytes (
204
- pyth_lazer_solana_contract:: ID ,
205
- & pyth_lazer_solana_contract:: instruction:: Initialize {
206
- top_authority : setup. payer . pubkey ( ) ,
207
- }
208
- . data ( ) ,
209
- vec ! [
210
- AccountMeta :: new( setup. payer. pubkey( ) , true ) ,
211
- AccountMeta :: new( pyth_lazer_solana_contract:: STORAGE_ID , false ) ,
212
- AccountMeta :: new_readonly( system_program:: ID , false ) ,
213
- ] ,
214
- ) ] ,
215
- Some ( & setup. payer . pubkey ( ) ) ,
211
+ async fn test_migrate_from_0_1_0 ( ) {
212
+ let mut program_test = program_test ( ) ;
213
+ // Create a storage PDA account with the data that was produced by the program v0.1.0.
214
+ let mut old_storage_data = hex:: decode (
215
+ "d175ffb9c4af4409aa4dcb5d31150b162b664abd843cb231cee5c0ebf759ce371d9cb36ffc653796\
216
+ 0174313a6525edf99936aa1477e94c72bc5cc617b21745f5f03296f3154461f214ffffffffffffff7\
217
+ f00000000000000000000000000000000000000000000000000000000000000000000000000000000",
218
+ )
219
+ . unwrap ( ) ;
220
+ let top_authority = Keypair :: new ( ) ;
221
+ // Replace top authority pubkey in storage PDA data to allow successful migration.
222
+ old_storage_data[ ANCHOR_DISCRIMINATOR_BYTES ..ANCHOR_DISCRIMINATOR_BYTES + PUBKEY_BYTES ]
223
+ . copy_from_slice ( & top_authority. pubkey ( ) . to_bytes ( ) ) ;
224
+ program_test. add_account (
225
+ pyth_lazer_solana_contract:: STORAGE_ID ,
226
+ Account {
227
+ lamports : 1733040 ,
228
+ data : old_storage_data,
229
+ owner : pyth_lazer_solana_contract:: ID ,
230
+ executable : false ,
231
+ rent_epoch : 18446744073709551615 ,
232
+ } ,
216
233
) ;
217
- transaction_init_contract. sign ( & [ & setup. payer ] , setup. recent_blockhash ) ;
218
- setup
219
- . banks_client
220
- . process_transaction ( transaction_init_contract)
221
- . await
222
- . unwrap ( ) ;
234
+ let mut setup = Setup :: with_program_test ( program_test) . await ;
235
+ let treasury = setup. create_treasury ( ) . await ;
223
236
237
+ // Make sure storage PDA will be rent-exempt after resize.
224
238
let tx_transfer = system_transaction:: transfer (
225
239
& setup. payer ,
226
240
& pyth_lazer_solana_contract:: STORAGE_ID ,
@@ -236,31 +250,30 @@ async fn test_with_init_v1_and_migrate() {
236
250
let mut transaction_migrate_contract = Transaction :: new_with_payer (
237
251
& [ Instruction :: new_with_bytes (
238
252
pyth_lazer_solana_contract:: ID ,
239
- & pyth_lazer_solana_contract:: instruction:: MigrateToStorageV2 { treasury } . data ( ) ,
253
+ & pyth_lazer_solana_contract:: instruction:: MigrateFrom010 { treasury } . data ( ) ,
240
254
vec ! [
241
- AccountMeta :: new( setup . payer . pubkey( ) , true ) ,
255
+ AccountMeta :: new( top_authority . pubkey( ) , true ) ,
242
256
AccountMeta :: new( pyth_lazer_solana_contract:: STORAGE_ID , false ) ,
243
257
AccountMeta :: new_readonly( system_program:: ID , false ) ,
244
258
] ,
245
259
) ] ,
246
260
Some ( & setup. payer . pubkey ( ) ) ,
247
261
) ;
248
- transaction_migrate_contract. sign ( & [ & setup. payer ] , setup. recent_blockhash ) ;
262
+ transaction_migrate_contract. sign ( & [ & setup. payer , & top_authority ] , setup. recent_blockhash ) ;
249
263
setup
250
264
. banks_client
251
265
. process_transaction ( transaction_migrate_contract)
252
266
. await
253
267
. unwrap ( ) ;
254
268
255
- let verifying_key =
256
- hex:: decode ( "74313a6525edf99936aa1477e94c72bc5cc617b21745f5f03296f3154461f214" ) . unwrap ( ) ;
257
269
let message = hex:: decode (
258
270
"b9011a82e5cddee2c1bd364c8c57e1c98a6a28d194afcad410ff412226c8b2ae931ff59a57147cb47c7307\
259
271
afc2a0a1abec4dd7e835a5b7113cf5aeac13a745c6bed6c60074313a6525edf99936aa1477e94c72bc5cc61\
260
272
7b21745f5f03296f3154461f2141c0075d3c7931c9773f30a240600010102000000010000e1f50500000000",
261
273
)
262
274
. unwrap ( ) ;
263
275
264
- setup. set_trusted ( verifying_key. try_into ( ) . unwrap ( ) ) . await ;
276
+ // The contract will recognize the trusted signer without calling `set_trusted`
277
+ // because it was present in the original storage PDA data.
265
278
setup. verify_message ( & message, treasury) . await ;
266
279
}
0 commit comments