Skip to content

Commit 1365ece

Browse files
authored
harness: don't stub program account if it was provided (#162)
1 parent 6394e51 commit 1365ece

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ clippy-fix:
8282
check-features:
8383
@cargo hack check --feature-powerset --no-dev-deps
8484

85+
build:
86+
@$(MAKE) build-test-programs
87+
@cargo build
88+
8589
test:
8690
@$(MAKE) build-test-programs
8791
@cargo test --all-features

harness/tests/system_program.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
mollusk_svm::{result::Check, Mollusk},
3-
solana_account::Account,
3+
solana_account::{Account, WritableAccount},
44
solana_instruction::error::InstructionError,
55
solana_pubkey::Pubkey,
66
solana_system_program::system_processor::DEFAULT_COMPUTE_UNITS,
@@ -103,3 +103,36 @@ fn test_transfer_bad_owner() {
103103

104104
Mollusk::default().process_and_validate_instruction(&instruction, &accounts, &checks);
105105
}
106+
107+
#[test]
108+
fn test_transfer_swap_program_account() {
109+
let sender = Pubkey::new_unique();
110+
let recipient = Pubkey::new_unique();
111+
112+
let base_lamports = 100_000_000u64;
113+
let transfer_amount = 42_000u64;
114+
115+
let instruction =
116+
solana_system_interface::instruction::transfer(&sender, &recipient, transfer_amount);
117+
118+
// Provide a custom program account instead of letting it be stubbed.
119+
let mut program_account = Account::new(1_000_000, 0, &solana_sdk_ids::native_loader::id());
120+
program_account.set_executable(true);
121+
122+
let accounts = [
123+
(
124+
sender,
125+
Account::new(base_lamports, 0, &solana_sdk_ids::system_program::id()),
126+
),
127+
(
128+
recipient,
129+
Account::new(base_lamports, 0, &solana_sdk_ids::system_program::id()),
130+
),
131+
(solana_sdk_ids::system_program::id(), program_account),
132+
];
133+
134+
// The test verifies that providing a custom program account does not panic.
135+
// Before the fix, Mollusk would always stub the program account, ignoring the
136+
// provided one. Now it uses the provided account if available.
137+
let _result = Mollusk::default().process_instruction(&instruction, &accounts);
138+
}

keys/src/accounts.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use {
44
crate::keys::KeyMap,
5-
mollusk_svm_error::error::{MolluskError, MolluskPanic},
5+
mollusk_svm_error::error::MolluskError,
66
solana_account::{Account, AccountSharedData},
77
solana_instruction::Instruction,
88
solana_pubkey::Pubkey,
@@ -56,17 +56,22 @@ pub fn compile_transaction_accounts_for_instruction(
5656
key_map
5757
.keys()
5858
.map(|key| {
59-
if let Some(stub_out_program_account) = &stub_out_program_account {
60-
if instruction.program_id == *key {
61-
return (*key, stub_out_program_account().into());
62-
}
63-
}
6459
let account = accounts
6560
.iter()
6661
.find(|(k, _)| k == key)
67-
.map(|(_, account)| AccountSharedData::from(account.clone()))
68-
.or_panic_with(MolluskError::AccountMissing(key));
69-
(*key, account)
62+
.map(|(_, account)| AccountSharedData::from(account.clone()));
63+
64+
if let Some(account) = account {
65+
(*key, account)
66+
} else if let Some(stub_out_program_account) = &stub_out_program_account {
67+
if instruction.program_id == *key {
68+
(*key, stub_out_program_account().into())
69+
} else {
70+
panic!("{}", MolluskError::AccountMissing(key))
71+
}
72+
} else {
73+
panic!("{}", MolluskError::AccountMissing(key))
74+
}
7075
})
7176
.collect()
7277
}
@@ -80,17 +85,22 @@ pub fn compile_transaction_accounts(
8085
key_map
8186
.keys()
8287
.map(|key| {
83-
if let Some(stub_out_program_account) = &stub_out_program_account {
84-
if instructions.iter().any(|ix| ix.program_id == *key) {
85-
return (*key, stub_out_program_account().into());
86-
}
87-
}
8888
let account = accounts
8989
.iter()
9090
.find(|(k, _)| k == key)
91-
.map(|(_, account)| AccountSharedData::from(account.clone()))
92-
.or_panic_with(MolluskError::AccountMissing(key));
93-
(*key, account)
91+
.map(|(_, account)| AccountSharedData::from(account.clone()));
92+
93+
if let Some(account) = account {
94+
(*key, account)
95+
} else if let Some(stub_out_program_account) = &stub_out_program_account {
96+
if instructions.iter().any(|ix| ix.program_id == *key) {
97+
(*key, stub_out_program_account().into())
98+
} else {
99+
panic!("{}", MolluskError::AccountMissing(key))
100+
}
101+
} else {
102+
panic!("{}", MolluskError::AccountMissing(key))
103+
}
94104
})
95105
.collect()
96106
}

0 commit comments

Comments
 (0)