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:
Tyera Eulberg 2022-04-20 21:18:12 -04:00 committed by GitHub
parent 96d977fd05
commit b42f34a7b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 38 deletions

1
Cargo.lock generated
View File

@ -4608,6 +4608,7 @@ dependencies = [
"solana-transaction-status",
"solana-version",
"solana-vote-program",
"spl-token-2022",
"thiserror",
"tokio",
"tokio-stream",

View File

@ -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"

View File

@ -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()),
}
}
}

View File

@ -3252,6 +3252,7 @@ dependencies = [
"solana-transaction-status",
"solana-version",
"solana-vote-program",
"spl-token-2022",
"thiserror",
"tokio",
"tokio-stream",

View File

@ -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(),

View File

@ -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(&params.pubkey)