* rpc: performance fix for getProgramAccounts
The accounts were gradually pushed into a vector, which produced
significant slowdowns for very large responses.
* rpc: rewrite loops using iterators
Co-authored-by: Christian Kamm <ckamm@delightful-solutions.de>
(cherry picked from commit f1bbf1d8b0
)
Co-authored-by: Christian Kamm <mail@ckamm.de>
This commit is contained in:
@ -339,18 +339,15 @@ impl JsonRpcRequestProcessor {
|
||||
pubkeys: Vec<Pubkey>,
|
||||
config: Option<RpcAccountInfoConfig>,
|
||||
) -> Result<RpcResponse<Vec<Option<UiAccount>>>> {
|
||||
let mut accounts: Vec<Option<UiAccount>> = vec![];
|
||||
|
||||
let config = config.unwrap_or_default();
|
||||
let bank = self.bank(config.commitment);
|
||||
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Base64);
|
||||
check_slice_and_encoding(&encoding, config.data_slice.is_some())?;
|
||||
|
||||
for pubkey in pubkeys {
|
||||
let response_account =
|
||||
get_encoded_account(&bank, &pubkey, encoding, config.data_slice)?;
|
||||
accounts.push(response_account)
|
||||
}
|
||||
let accounts = pubkeys
|
||||
.into_iter()
|
||||
.map(|pubkey| get_encoded_account(&bank, &pubkey, encoding, config.data_slice))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
Ok(new_response(&bank, accounts))
|
||||
}
|
||||
|
||||
@ -384,19 +381,21 @@ impl JsonRpcRequestProcessor {
|
||||
self.get_filtered_program_accounts(&bank, program_id, filters)?
|
||||
}
|
||||
};
|
||||
let result =
|
||||
if program_id == &spl_token_id_v2_0() && encoding == UiAccountEncoding::JsonParsed {
|
||||
get_parsed_token_accounts(bank.clone(), keyed_accounts.into_iter()).collect()
|
||||
} else {
|
||||
let mut encoded_accounts = vec![];
|
||||
for (pubkey, account) in keyed_accounts {
|
||||
encoded_accounts.push(RpcKeyedAccount {
|
||||
let result = if program_id == &spl_token_id_v2_0()
|
||||
&& encoding == UiAccountEncoding::JsonParsed
|
||||
{
|
||||
get_parsed_token_accounts(bank.clone(), keyed_accounts.into_iter()).collect()
|
||||
} else {
|
||||
keyed_accounts
|
||||
.into_iter()
|
||||
.map(|(pubkey, account)| {
|
||||
Ok(RpcKeyedAccount {
|
||||
pubkey: pubkey.to_string(),
|
||||
account: encode_account(&account, &pubkey, encoding, data_slice_config)?,
|
||||
});
|
||||
}
|
||||
encoded_accounts
|
||||
};
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
};
|
||||
Ok(result).map(|result| match with_context {
|
||||
true => OptionalContext::Context(new_response(&bank, result)),
|
||||
false => OptionalContext::NoContext(result),
|
||||
@ -2728,10 +2727,10 @@ pub mod rpc_full {
|
||||
max_multiple_accounts
|
||||
)));
|
||||
}
|
||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
||||
for pubkey_str in pubkey_strs {
|
||||
pubkeys.push(verify_pubkey(&pubkey_str)?);
|
||||
}
|
||||
let pubkeys = pubkey_strs
|
||||
.into_iter()
|
||||
.map(|pubkey_str| verify_pubkey(&pubkey_str))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
meta.get_multiple_accounts(pubkeys, config)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user