* 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 <ckamm@delightful-solutions.de>
(cherry picked from commit f1bbf1d8b0
)
# Conflicts:
# core/src/rpc.rs
* fix conflicts
* Fix conflicts
Co-authored-by: Christian Kamm <mail@ckamm.de>
Co-authored-by: Justin Starry <justin@solana.com>
Co-authored-by: Tyera Eulberg <tyera@solana.com>
This commit is contained in:
@ -328,18 +328,15 @@ impl JsonRpcRequestProcessor {
|
|||||||
pubkeys: Vec<Pubkey>,
|
pubkeys: Vec<Pubkey>,
|
||||||
config: Option<RpcAccountInfoConfig>,
|
config: Option<RpcAccountInfoConfig>,
|
||||||
) -> Result<RpcResponse<Vec<Option<UiAccount>>>> {
|
) -> Result<RpcResponse<Vec<Option<UiAccount>>>> {
|
||||||
let mut accounts: Vec<Option<UiAccount>> = vec![];
|
|
||||||
|
|
||||||
let config = config.unwrap_or_default();
|
let config = config.unwrap_or_default();
|
||||||
let bank = self.bank(config.commitment);
|
let bank = self.bank(config.commitment);
|
||||||
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Base64);
|
let encoding = config.encoding.unwrap_or(UiAccountEncoding::Base64);
|
||||||
check_slice_and_encoding(&encoding, config.data_slice.is_some())?;
|
check_slice_and_encoding(&encoding, config.data_slice.is_some())?;
|
||||||
|
|
||||||
for pubkey in pubkeys {
|
let accounts = pubkeys
|
||||||
let response_account =
|
.into_iter()
|
||||||
get_encoded_account(&bank, &pubkey, encoding, config.data_slice)?;
|
.map(|pubkey| get_encoded_account(&bank, &pubkey, encoding, config.data_slice))
|
||||||
accounts.push(response_account)
|
.collect::<Result<Vec<_>>>()?;
|
||||||
}
|
|
||||||
Ok(new_response(&bank, accounts))
|
Ok(new_response(&bank, accounts))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,17 +376,19 @@ impl JsonRpcRequestProcessor {
|
|||||||
} else {
|
} else {
|
||||||
keyed_accounts
|
keyed_accounts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(pubkey, account)| RpcKeyedAccount {
|
.map(|(pubkey, account)| {
|
||||||
pubkey: pubkey.to_string(),
|
Ok(RpcKeyedAccount {
|
||||||
account: UiAccount::encode(
|
pubkey: pubkey.to_string(),
|
||||||
&pubkey,
|
account: UiAccount::encode(
|
||||||
&account,
|
&pubkey,
|
||||||
encoding,
|
&account,
|
||||||
None,
|
encoding,
|
||||||
data_slice_config,
|
None,
|
||||||
),
|
data_slice_config,
|
||||||
|
),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.collect()
|
.collect::<Result<Vec<_>>>()?
|
||||||
};
|
};
|
||||||
Ok(result).map(|result| match with_context {
|
Ok(result).map(|result| match with_context {
|
||||||
true => OptionalContext::Context(new_response(&bank, result)),
|
true => OptionalContext::Context(new_response(&bank, result)),
|
||||||
@ -2804,10 +2803,10 @@ pub mod rpc_full {
|
|||||||
max_multiple_accounts
|
max_multiple_accounts
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
let pubkeys = pubkey_strs
|
||||||
for pubkey_str in pubkey_strs {
|
.into_iter()
|
||||||
pubkeys.push(verify_pubkey(&pubkey_str)?);
|
.map(|pubkey_str| verify_pubkey(&pubkey_str))
|
||||||
}
|
.collect::<Result<Vec<_>>>()?;
|
||||||
meta.get_multiple_accounts(pubkeys, config)
|
meta.get_multiple_accounts(pubkeys, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user