@@ -9,13 +9,47 @@ use solana_rent::Rent;
99use solana_system_interface:: instruction:: create_account;
1010use solana_transaction:: Transaction ;
1111
12+ // The .so is built into ../../tests/fixtures by `pnpm build-and-test` (which runs
13+ // `cargo build-sbf --sbf-out-dir=./tests/fixtures` from the package root). Run
14+ // that script (or `cargo build-sbf` with --sbf-out-dir set accordingly) before
15+ // `cargo test`.
16+ const PROGRAM_SO : & [ u8 ] = include_bytes ! ( "../../tests/fixtures/counter_solana_native.so" ) ;
17+
18+ fn setup_with_counter ( ) -> ( LiteSVM , Pubkey , Keypair , Keypair ) {
19+ let program_id = Pubkey :: new_unique ( ) ;
20+
21+ let mut svm = LiteSVM :: new ( ) ;
22+ svm. add_program ( program_id, PROGRAM_SO ) . unwrap ( ) ;
23+
24+ let payer = Keypair :: new ( ) ;
25+ let counter_account = Keypair :: new ( ) ;
26+
27+ svm. airdrop ( & payer. pubkey ( ) , LAMPORTS_PER_SOL * 10 ) . unwrap ( ) ;
28+
29+ let counter_account_size = std:: mem:: size_of :: < Counter > ( ) ;
30+ let create_ix = create_account (
31+ & payer. pubkey ( ) ,
32+ & counter_account. pubkey ( ) ,
33+ Rent :: default ( ) . minimum_balance ( counter_account_size) ,
34+ counter_account_size as u64 ,
35+ & program_id,
36+ ) ;
37+ let tx = Transaction :: new_signed_with_payer (
38+ & [ create_ix] ,
39+ Some ( & payer. pubkey ( ) ) ,
40+ & [ & payer, & counter_account] ,
41+ svm. latest_blockhash ( ) ,
42+ ) ;
43+ svm. send_transaction ( tx) . unwrap ( ) ;
44+ ( svm, program_id, payer, counter_account)
45+ }
46+
1247#[ test]
1348fn test_counter ( ) {
1449 let program_id = Pubkey :: new_unique ( ) ;
15- let program_bytes = include_bytes ! ( "../../tests/fixtures/counter_solana_native.so" ) ;
1650
1751 let mut svm = LiteSVM :: new ( ) ;
18- svm. add_program ( program_id, program_bytes ) . unwrap ( ) ;
52+ svm. add_program ( program_id, PROGRAM_SO ) . unwrap ( ) ;
1953
2054 let payer = Keypair :: new ( ) ;
2155 let counter_account = Keypair :: new ( ) ;
@@ -38,7 +72,7 @@ fn test_counter() {
3872 & [ & payer, & counter_account] ,
3973 svm. latest_blockhash ( ) ,
4074 ) ;
41- assert ! ( svm. send_transaction( tx) . is_ok ( ) ) ;
75+ svm. send_transaction ( tx) . unwrap ( ) ;
4276
4377 let ix = Instruction {
4478 program_id,
@@ -53,9 +87,79 @@ fn test_counter() {
5387 svm. latest_blockhash ( ) ,
5488 ) ;
5589
56- let _ = svm. send_transaction ( tx) . is_ok ( ) ;
90+ // Actually assert the transaction succeeded - the previous shape used
91+ // `let _ = ...is_ok();` which discarded the result.
92+ svm. send_transaction ( tx) . unwrap ( ) ;
5793
5894 let counter_account_data = svm. get_account ( & counter_account. pubkey ( ) ) . unwrap ( ) . data ;
5995 let counter = Counter :: try_from_slice ( & counter_account_data) . unwrap ( ) ;
6096 assert_eq ! ( counter. count, 1 ) ;
6197}
98+
99+ #[ test]
100+ fn test_unknown_instruction_fails ( ) {
101+ let ( mut svm, program_id, payer, counter_account) = setup_with_counter ( ) ;
102+
103+ // Discriminant 9 is not handled and must now return an error rather than Ok(()).
104+ let ix = Instruction {
105+ program_id,
106+ accounts : vec ! [ AccountMeta :: new( counter_account. pubkey( ) , false ) ] ,
107+ data : vec ! [ 9 ] ,
108+ } ;
109+ let tx = Transaction :: new_signed_with_payer (
110+ & [ ix] ,
111+ Some ( & payer. pubkey ( ) ) ,
112+ & [ & payer] ,
113+ svm. latest_blockhash ( ) ,
114+ ) ;
115+ assert ! (
116+ svm. send_transaction( tx) . is_err( ) ,
117+ "unknown instruction discriminant must fail"
118+ ) ;
119+ }
120+
121+ #[ test]
122+ fn test_wrong_owner_fails ( ) {
123+ let program_id = Pubkey :: new_unique ( ) ;
124+
125+ let mut svm = LiteSVM :: new ( ) ;
126+ svm. add_program ( program_id, PROGRAM_SO ) . unwrap ( ) ;
127+
128+ let payer = Keypair :: new ( ) ;
129+ let counter_account = Keypair :: new ( ) ;
130+ svm. airdrop ( & payer. pubkey ( ) , LAMPORTS_PER_SOL * 10 ) . unwrap ( ) ;
131+
132+ // Create the counter account but owned by a different (random) program.
133+ let counter_account_size = std:: mem:: size_of :: < Counter > ( ) ;
134+ let wrong_owner = Pubkey :: new_unique ( ) ;
135+ let create_ix = create_account (
136+ & payer. pubkey ( ) ,
137+ & counter_account. pubkey ( ) ,
138+ Rent :: default ( ) . minimum_balance ( counter_account_size) ,
139+ counter_account_size as u64 ,
140+ & wrong_owner,
141+ ) ;
142+ let tx = Transaction :: new_signed_with_payer (
143+ & [ create_ix] ,
144+ Some ( & payer. pubkey ( ) ) ,
145+ & [ & payer, & counter_account] ,
146+ svm. latest_blockhash ( ) ,
147+ ) ;
148+ svm. send_transaction ( tx) . unwrap ( ) ;
149+
150+ let ix = Instruction {
151+ program_id,
152+ accounts : vec ! [ AccountMeta :: new( counter_account. pubkey( ) , false ) ] ,
153+ data : vec ! [ 0 ] ,
154+ } ;
155+ let tx = Transaction :: new_signed_with_payer (
156+ & [ ix] ,
157+ Some ( & payer. pubkey ( ) ) ,
158+ & [ & payer] ,
159+ svm. latest_blockhash ( ) ,
160+ ) ;
161+ assert ! (
162+ svm. send_transaction( tx) . is_err( ) ,
163+ "counter owned by a different program must be rejected"
164+ ) ;
165+ }
0 commit comments