Skip to content

Commit

Permalink
rpc: performance fix for getProgramAccounts (backport #19941) (#19949)
Browse files Browse the repository at this point in the history
* rpc: performance fix for getProgramAccounts (#19941)

* 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 <[email protected]>
(cherry picked from commit f1bbf1d)

# Conflicts:
#	core/src/rpc.rs

* fix conflicts

* Fix conflicts

Co-authored-by: Christian Kamm <[email protected]>
Co-authored-by: Justin Starry <[email protected]>
Co-authored-by: Tyera Eulberg <[email protected]>
  • Loading branch information
4 people authored Sep 16, 2021
1 parent ccef24c commit da7185e
Showing 1 changed file with 20 additions and 21 deletions.
41 changes: 20 additions & 21 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,18 +328,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))
}

Expand Down Expand Up @@ -379,17 +376,19 @@ impl JsonRpcRequestProcessor {
} else {
keyed_accounts
.into_iter()
.map(|(pubkey, account)| RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(
&pubkey,
&account,
encoding,
None,
data_slice_config,
),
.map(|(pubkey, account)| {
Ok(RpcKeyedAccount {
pubkey: pubkey.to_string(),
account: UiAccount::encode(
&pubkey,
&account,
encoding,
None,
data_slice_config,
),
})
})
.collect()
.collect::<Result<Vec<_>>>()?
};
Ok(result).map(|result| match with_context {
true => OptionalContext::Context(new_response(&bank, result)),
Expand Down Expand Up @@ -2804,10 +2803,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)
}

Expand Down

0 comments on commit da7185e

Please sign in to comment.