Rpc: filters performance improvement (#20185)
* Add Base58,Base64,Bytes to MemcmpEncodedBytes * Rpc: decode memcmp before filtering accounts * Add deprecated attribute * Add Memcmp::bytes * Fix clippy for deprecated * Another clippy fix * merge RpcFilterError::DataTooLarge * add deprecation for Base58DataTooLarge * change filter data size limit * strict data size len for base58 * add magic numbers * fix tests
This commit is contained in:
@ -1704,7 +1704,7 @@ impl JsonRpcRequestProcessor {
|
||||
// Optional filter on Mint address
|
||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(mint.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Bytes(mint.to_bytes().into()),
|
||||
encoding: None,
|
||||
}));
|
||||
}
|
||||
@ -1748,15 +1748,13 @@ impl JsonRpcRequestProcessor {
|
||||
// Filter on Delegate is_some()
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 72,
|
||||
bytes: MemcmpEncodedBytes::Binary(
|
||||
bs58::encode(bincode::serialize(&1u32).unwrap()).into_string(),
|
||||
),
|
||||
bytes: MemcmpEncodedBytes::Bytes(bincode::serialize(&1u32).unwrap()),
|
||||
encoding: None,
|
||||
}),
|
||||
// Filter on Delegate address
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 76,
|
||||
bytes: MemcmpEncodedBytes::Binary(delegate.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Bytes(delegate.to_bytes().into()),
|
||||
encoding: None,
|
||||
}),
|
||||
];
|
||||
@ -1795,8 +1793,9 @@ impl JsonRpcRequestProcessor {
|
||||
&self,
|
||||
bank: &Arc<Bank>,
|
||||
program_id: &Pubkey,
|
||||
filters: Vec<RpcFilterType>,
|
||||
mut filters: Vec<RpcFilterType>,
|
||||
) -> RpcCustomResult<Vec<(Pubkey, AccountSharedData)>> {
|
||||
optimize_filters(&mut filters);
|
||||
let filter_closure = |account: &AccountSharedData| {
|
||||
filters.iter().all(|filter_type| match filter_type {
|
||||
RpcFilterType::DataSize(size) => account.data().len() as u64 == *size,
|
||||
@ -1853,7 +1852,7 @@ impl JsonRpcRequestProcessor {
|
||||
// Filter on Owner address
|
||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_OWNER_OFFSET,
|
||||
bytes: MemcmpEncodedBytes::Binary(owner_key.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Bytes(owner_key.to_bytes().into()),
|
||||
encoding: None,
|
||||
}));
|
||||
|
||||
@ -1867,6 +1866,7 @@ impl JsonRpcRequestProcessor {
|
||||
index_key: owner_key.to_string(),
|
||||
});
|
||||
}
|
||||
optimize_filters(&mut filters);
|
||||
Ok(bank
|
||||
.get_filtered_indexed_accounts(&IndexKey::SplTokenOwner(*owner_key), |account| {
|
||||
account.owner() == &spl_token_id_v2_0()
|
||||
@ -1902,7 +1902,7 @@ impl JsonRpcRequestProcessor {
|
||||
// Filter on Mint address
|
||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_MINT_OFFSET,
|
||||
bytes: MemcmpEncodedBytes::Binary(mint_key.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Bytes(mint_key.to_bytes().into()),
|
||||
encoding: None,
|
||||
}));
|
||||
if self
|
||||
@ -1915,6 +1915,7 @@ impl JsonRpcRequestProcessor {
|
||||
index_key: mint_key.to_string(),
|
||||
});
|
||||
}
|
||||
optimize_filters(&mut filters);
|
||||
Ok(bank
|
||||
.get_filtered_indexed_accounts(&IndexKey::SplTokenMint(*mint_key), |account| {
|
||||
account.owner() == &spl_token_id_v2_0()
|
||||
@ -1970,6 +1971,24 @@ impl JsonRpcRequestProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
fn optimize_filters(filters: &mut Vec<RpcFilterType>) {
|
||||
filters.iter_mut().for_each(|filter_type| {
|
||||
if let RpcFilterType::Memcmp(compare) = filter_type {
|
||||
use MemcmpEncodedBytes::*;
|
||||
match &compare.bytes {
|
||||
#[allow(deprecated)]
|
||||
Binary(bytes) | Base58(bytes) => {
|
||||
compare.bytes = Bytes(bs58::decode(bytes).into_vec().unwrap());
|
||||
}
|
||||
Base64(bytes) => {
|
||||
compare.bytes = Bytes(base64::decode(bytes).unwrap());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn verify_transaction(
|
||||
transaction: &SanitizedTransaction,
|
||||
feature_set: &Arc<feature_set::FeatureSet>,
|
||||
@ -2136,7 +2155,7 @@ fn get_spl_token_owner_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
||||
RpcFilterType::DataSize(size) => data_size_filter = Some(*size),
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_OWNER_OFFSET,
|
||||
bytes: MemcmpEncodedBytes::Binary(bytes),
|
||||
bytes: MemcmpEncodedBytes::Base58(bytes),
|
||||
..
|
||||
}) => {
|
||||
if let Ok(key) = Pubkey::from_str(bytes) {
|
||||
@ -2164,7 +2183,7 @@ fn get_spl_token_mint_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
||||
RpcFilterType::DataSize(size) => data_size_filter = Some(*size),
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_MINT_OFFSET,
|
||||
bytes: MemcmpEncodedBytes::Binary(bytes),
|
||||
bytes: MemcmpEncodedBytes::Base58(bytes),
|
||||
..
|
||||
}) => {
|
||||
if let Ok(key) = Pubkey::from_str(bytes) {
|
||||
@ -6132,7 +6151,7 @@ pub mod tests {
|
||||
fn test_rpc_verify_filter() {
|
||||
let filter = RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(
|
||||
bytes: MemcmpEncodedBytes::Base58(
|
||||
"13LeFbG6m2EP1fqCj9k66fcXsoTHMMtgr7c78AivUrYD".to_string(),
|
||||
),
|
||||
encoding: None,
|
||||
@ -6141,7 +6160,7 @@ pub mod tests {
|
||||
// Invalid base-58
|
||||
let filter = RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary("III".to_string()),
|
||||
bytes: MemcmpEncodedBytes::Base58("III".to_string()),
|
||||
encoding: None,
|
||||
});
|
||||
assert!(verify_filter(&filter).is_err());
|
||||
@ -7646,7 +7665,7 @@ pub mod tests {
|
||||
&[
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 32,
|
||||
bytes: MemcmpEncodedBytes::Binary(owner.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Base58(owner.to_string()),
|
||||
encoding: None
|
||||
}),
|
||||
RpcFilterType::DataSize(165)
|
||||
@ -7662,7 +7681,7 @@ pub mod tests {
|
||||
&[
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(owner.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Base58(owner.to_string()),
|
||||
encoding: None
|
||||
}),
|
||||
RpcFilterType::DataSize(165)
|
||||
@ -7676,7 +7695,7 @@ pub mod tests {
|
||||
&[
|
||||
RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 32,
|
||||
bytes: MemcmpEncodedBytes::Binary(owner.to_string()),
|
||||
bytes: MemcmpEncodedBytes::Base58(owner.to_string()),
|
||||
encoding: None
|
||||
}),
|
||||
RpcFilterType::DataSize(165)
|
||||
|
Reference in New Issue
Block a user