Skip to content

Commit 964cd5e

Browse files
committed
make account compilation take an iter
1 parent 369c405 commit 964cd5e

File tree

5 files changed

+58
-38
lines changed

5 files changed

+58
-38
lines changed

harness/src/compile_accounts.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ pub struct CompiledAccounts {
2121
pub transaction_accounts: Vec<TransactionAccount>,
2222
}
2323

24-
pub fn compile_accounts(
24+
pub fn compile_accounts<'a>(
2525
instruction: &Instruction,
26-
accounts: &[(Pubkey, Account)],
26+
accounts: impl Iterator<Item = &'a (Pubkey, Account)>,
2727
loader_key: Pubkey,
2828
) -> CompiledAccounts {
2929
let stub_out_program_account = move || {

harness/src/fuzz/firedancer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn build_fixture_context(
7373
instruction_accounts,
7474
transaction_accounts,
7575
..
76-
} = compile_accounts(instruction, accounts, loader_key);
76+
} = compile_accounts(instruction, accounts.iter(), loader_key);
7777

7878
let accounts = transaction_accounts
7979
.into_iter()

harness/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ impl Mollusk {
812812
program_id_index,
813813
instruction_accounts,
814814
transaction_accounts,
815-
} = crate::compile_accounts::compile_accounts(instruction, accounts, loader_key);
815+
} = crate::compile_accounts::compile_accounts(instruction, accounts.iter(), loader_key);
816816

817817
self.process_instruction_inner(
818818
instruction,
@@ -850,7 +850,7 @@ impl Mollusk {
850850
program_id_index,
851851
instruction_accounts,
852852
transaction_accounts,
853-
} = crate::compile_accounts::compile_accounts(instruction, accounts, loader_key);
853+
} = crate::compile_accounts::compile_accounts(instruction, accounts.iter(), loader_key);
854854

855855
let this_result = self.process_instruction_inner(
856856
instruction,
@@ -904,7 +904,7 @@ impl Mollusk {
904904
program_id_index,
905905
instruction_accounts,
906906
transaction_accounts,
907-
} = crate::compile_accounts::compile_accounts(instruction, accounts, loader_key);
907+
} = crate::compile_accounts::compile_accounts(instruction, accounts.iter(), loader_key);
908908

909909
let result = self.process_instruction_inner(
910910
instruction,
@@ -963,7 +963,7 @@ impl Mollusk {
963963
program_id_index,
964964
instruction_accounts,
965965
transaction_accounts,
966-
} = crate::compile_accounts::compile_accounts(instruction, accounts, loader_key);
966+
} = crate::compile_accounts::compile_accounts(instruction, accounts.iter(), loader_key);
967967

968968
let this_result = self.process_instruction_inner(
969969
instruction,

keys/src/accounts.rs

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
33
use {
44
crate::keys::KeyMap,
5-
mollusk_svm_error::error::MolluskError,
5+
mollusk_svm_error::error::{MolluskError, MolluskPanic},
66
solana_account::{Account, AccountSharedData},
77
solana_instruction::Instruction,
88
solana_pubkey::Pubkey,
99
solana_transaction_context::{IndexOfAccount, InstructionAccount, TransactionAccount},
10+
std::collections::HashMap,
1011
};
1112

1213
// Helper struct to avoid cloning instruction data.
@@ -47,60 +48,64 @@ pub fn compile_instruction_accounts(
4748
.collect()
4849
}
4950

50-
pub fn compile_transaction_accounts_for_instruction(
51+
pub fn compile_transaction_accounts_for_instruction<'a>(
5152
key_map: &KeyMap,
5253
instruction: &Instruction,
53-
accounts: &[(Pubkey, Account)],
54+
accounts: impl Iterator<Item = &'a (Pubkey, Account)>,
5455
stub_out_program_account: Option<Box<dyn Fn() -> Account>>,
5556
) -> Vec<TransactionAccount> {
57+
let len = key_map.len();
58+
let mut by_key: HashMap<Pubkey, AccountSharedData> = HashMap::with_capacity(len);
59+
60+
for (key, account) in accounts {
61+
if key_map.contains_key(key) {
62+
by_key.insert(*key, AccountSharedData::from(account.clone()));
63+
}
64+
}
65+
5666
key_map
5767
.keys()
5868
.map(|key| {
59-
let account = accounts
60-
.iter()
61-
.find(|(k, _)| k == key)
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 {
69+
if let Some(stub_out_program_account) = &stub_out_program_account {
6770
if instruction.program_id == *key {
68-
(*key, stub_out_program_account().into())
69-
} else {
70-
panic!("{}", MolluskError::AccountMissing(key))
71+
return (*key, stub_out_program_account().into());
7172
}
72-
} else {
73-
panic!("{}", MolluskError::AccountMissing(key))
7473
}
74+
let account = by_key
75+
.remove(key)
76+
.or_panic_with(MolluskError::AccountMissing(key));
77+
(*key, account)
7578
})
7679
.collect()
7780
}
7881

79-
pub fn compile_transaction_accounts(
82+
pub fn compile_transaction_accounts<'a>(
8083
key_map: &KeyMap,
8184
instructions: &[Instruction],
82-
accounts: &[(Pubkey, Account)],
85+
accounts: impl Iterator<Item = &'a (Pubkey, Account)>,
8386
stub_out_program_account: Option<Box<dyn Fn() -> Account>>,
8487
) -> Vec<TransactionAccount> {
88+
let len = key_map.len();
89+
let mut by_key: HashMap<Pubkey, AccountSharedData> = HashMap::with_capacity(len);
90+
91+
for (key, account) in accounts {
92+
if key_map.contains_key(key) {
93+
by_key.insert(*key, AccountSharedData::from(account.clone()));
94+
}
95+
}
96+
8597
key_map
8698
.keys()
8799
.map(|key| {
88-
let account = accounts
89-
.iter()
90-
.find(|(k, _)| k == key)
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 {
100+
if let Some(stub_out_program_account) = &stub_out_program_account {
96101
if instructions.iter().any(|ix| ix.program_id == *key) {
97-
(*key, stub_out_program_account().into())
98-
} else {
99-
panic!("{}", MolluskError::AccountMissing(key))
102+
return (*key, stub_out_program_account().into());
100103
}
101-
} else {
102-
panic!("{}", MolluskError::AccountMissing(key))
103104
}
105+
let account = by_key
106+
.remove(key)
107+
.or_panic_with(MolluskError::AccountMissing(key));
108+
(*key, account)
104109
})
105110
.collect()
106111
}

keys/src/keys.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,21 @@ impl KeyMap {
181181
pub fn position(&self, key: &Pubkey) -> Option<usize> {
182182
self.map.keys().position(|k| k == key)
183183
}
184+
185+
/// Return whether or not the map contains a key.
186+
pub fn contains_key(&self, key: &Pubkey) -> bool {
187+
self.map.contains_key(key)
188+
}
189+
190+
/// Get the length of the key map.
191+
pub fn len(&self) -> usize {
192+
self.map.len()
193+
}
194+
195+
/// Return whether or not the key map is empty.
196+
pub fn is_empty(&self) -> bool {
197+
self.map.is_empty()
198+
}
184199
}
185200

186201
#[cfg(test)]

0 commit comments

Comments
 (0)