Update Rpc filters to support token-2022 (#24541)
* Add TokenAccountState rpc_filter * Use a method on RpcFliterType instead of helper
This commit is contained in:
parent
96d977fd05
commit
b42f34a7b8
|
@ -4608,6 +4608,7 @@ dependencies = [
|
|||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
|
|
@ -48,6 +48,7 @@ solana-streamer = { path = "../streamer", version = "=1.11.0" }
|
|||
solana-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
|
||||
solana-version = { path = "../version", version = "=1.11.0" }
|
||||
solana-vote-program = { path = "../programs/vote", version = "=1.11.0" }
|
||||
spl-token-2022 = { version = "=0.2.0", features = ["no-entrypoint"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
tokio-stream = "0.1.8"
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![allow(deprecated)]
|
||||
use {std::borrow::Cow, thiserror::Error};
|
||||
use {
|
||||
solana_sdk::account::{AccountSharedData, ReadableAccount},
|
||||
spl_token_2022::{generic_token_account::GenericTokenAccount, state::Account},
|
||||
std::borrow::Cow,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
const MAX_DATA_SIZE: usize = 128;
|
||||
const MAX_DATA_BASE58_SIZE: usize = 175;
|
||||
|
@ -10,6 +15,7 @@ const MAX_DATA_BASE64_SIZE: usize = 172;
|
|||
pub enum RpcFilterType {
|
||||
DataSize(u64),
|
||||
Memcmp(Memcmp),
|
||||
TokenAccountState,
|
||||
}
|
||||
|
||||
impl RpcFilterType {
|
||||
|
@ -68,6 +74,15 @@ impl RpcFilterType {
|
|||
}
|
||||
}
|
||||
}
|
||||
RpcFilterType::TokenAccountState => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allows(&self, account: &AccountSharedData) -> bool {
|
||||
match self {
|
||||
RpcFilterType::DataSize(size) => account.data().len() as u64 == *size,
|
||||
RpcFilterType::Memcmp(compare) => compare.bytes_match(account.data()),
|
||||
RpcFilterType::TokenAccountState => Account::valid_account_data(account.data()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3252,6 +3252,7 @@ dependencies = [
|
|||
"solana-transaction-status",
|
||||
"solana-version",
|
||||
"solana-vote-program",
|
||||
"spl-token-2022",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
|
|
@ -1898,10 +1898,9 @@ impl JsonRpcRequestProcessor {
|
|||
) -> 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,
|
||||
RpcFilterType::Memcmp(compare) => compare.bytes_match(account.data()),
|
||||
})
|
||||
filters
|
||||
.iter()
|
||||
.all(|filter_type| filter_type.allows(account))
|
||||
};
|
||||
if self
|
||||
.config
|
||||
|
@ -1954,9 +1953,7 @@ impl JsonRpcRequestProcessor {
|
|||
// later updates. We include the redundant filters here to avoid returning these accounts.
|
||||
//
|
||||
// Filter on Token Account state
|
||||
filters.push(RpcFilterType::DataSize(
|
||||
TokenAccount::get_packed_len() as u64
|
||||
));
|
||||
filters.push(RpcFilterType::TokenAccountState);
|
||||
// Filter on Owner address
|
||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_OWNER_OFFSET,
|
||||
|
@ -1979,14 +1976,9 @@ impl JsonRpcRequestProcessor {
|
|||
&IndexKey::SplTokenOwner(*owner_key),
|
||||
|account| {
|
||||
account.owner() == program_id
|
||||
&& filters.iter().all(|filter_type| match filter_type {
|
||||
RpcFilterType::DataSize(size) => {
|
||||
account.data().len() as u64 == *size
|
||||
}
|
||||
RpcFilterType::Memcmp(compare) => {
|
||||
compare.bytes_match(account.data())
|
||||
}
|
||||
})
|
||||
&& filters
|
||||
.iter()
|
||||
.all(|filter_type| filter_type.allows(account))
|
||||
},
|
||||
&ScanConfig::default(),
|
||||
bank.byte_limit_for_scans(),
|
||||
|
@ -2013,9 +2005,7 @@ impl JsonRpcRequestProcessor {
|
|||
// updates. We include the redundant filters here to avoid returning these accounts.
|
||||
//
|
||||
// Filter on Token Account state
|
||||
filters.push(RpcFilterType::DataSize(
|
||||
TokenAccount::get_packed_len() as u64
|
||||
));
|
||||
filters.push(RpcFilterType::TokenAccountState);
|
||||
// Filter on Mint address
|
||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||
offset: SPL_TOKEN_ACCOUNT_MINT_OFFSET,
|
||||
|
@ -2037,14 +2027,9 @@ impl JsonRpcRequestProcessor {
|
|||
&IndexKey::SplTokenMint(*mint_key),
|
||||
|account| {
|
||||
account.owner() == program_id
|
||||
&& filters.iter().all(|filter_type| match filter_type {
|
||||
RpcFilterType::DataSize(size) => {
|
||||
account.data().len() as u64 == *size
|
||||
}
|
||||
RpcFilterType::Memcmp(compare) => {
|
||||
compare.bytes_match(account.data())
|
||||
}
|
||||
})
|
||||
&& filters
|
||||
.iter()
|
||||
.all(|filter_type| filter_type.allows(account))
|
||||
},
|
||||
&ScanConfig::default(),
|
||||
bank.byte_limit_for_scans(),
|
||||
|
|
|
@ -15,13 +15,10 @@ use {
|
|||
rayon::prelude::*,
|
||||
serde::Serialize,
|
||||
solana_account_decoder::{parse_token::is_known_spl_token_id, UiAccount, UiAccountEncoding},
|
||||
solana_client::{
|
||||
rpc_filter::RpcFilterType,
|
||||
rpc_response::{
|
||||
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcBlockUpdate,
|
||||
RpcBlockUpdateError, RpcKeyedAccount, RpcLogsResponse, RpcResponseContext,
|
||||
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
solana_client::rpc_response::{
|
||||
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcBlockUpdate,
|
||||
RpcBlockUpdateError, RpcKeyedAccount, RpcLogsResponse, RpcResponseContext,
|
||||
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
||||
},
|
||||
solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path},
|
||||
solana_measure::measure::Measure,
|
||||
|
@ -400,10 +397,9 @@ fn filter_program_results(
|
|||
let encoding = params.encoding;
|
||||
let filters = params.filters.clone();
|
||||
let keyed_accounts = accounts.into_iter().filter(move |(_, account)| {
|
||||
filters.iter().all(|filter_type| match filter_type {
|
||||
RpcFilterType::DataSize(size) => account.data().len() as u64 == *size,
|
||||
RpcFilterType::Memcmp(compare) => compare.bytes_match(account.data()),
|
||||
})
|
||||
filters
|
||||
.iter()
|
||||
.all(|filter_type| filter_type.allows(account))
|
||||
});
|
||||
let accounts: Box<dyn Iterator<Item = RpcKeyedAccount>> =
|
||||
if is_known_spl_token_id(¶ms.pubkey)
|
||||
|
|
Loading…
Reference in New Issue