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-transaction-status",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
"solana-vote-program",
|
"solana-vote-program",
|
||||||
|
"spl-token-2022",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"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-transaction-status = { path = "../transaction-status", version = "=1.11.0" }
|
||||||
solana-version = { path = "../version", version = "=1.11.0" }
|
solana-version = { path = "../version", version = "=1.11.0" }
|
||||||
solana-vote-program = { path = "../programs/vote", 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"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tokio-stream = "0.1.8"
|
tokio-stream = "0.1.8"
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
#![allow(deprecated)]
|
#![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_SIZE: usize = 128;
|
||||||
const MAX_DATA_BASE58_SIZE: usize = 175;
|
const MAX_DATA_BASE58_SIZE: usize = 175;
|
||||||
|
@ -10,6 +15,7 @@ const MAX_DATA_BASE64_SIZE: usize = 172;
|
||||||
pub enum RpcFilterType {
|
pub enum RpcFilterType {
|
||||||
DataSize(u64),
|
DataSize(u64),
|
||||||
Memcmp(Memcmp),
|
Memcmp(Memcmp),
|
||||||
|
TokenAccountState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RpcFilterType {
|
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-transaction-status",
|
||||||
"solana-version",
|
"solana-version",
|
||||||
"solana-vote-program",
|
"solana-vote-program",
|
||||||
|
"spl-token-2022",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
|
|
|
@ -1898,10 +1898,9 @@ impl JsonRpcRequestProcessor {
|
||||||
) -> RpcCustomResult<Vec<(Pubkey, AccountSharedData)>> {
|
) -> RpcCustomResult<Vec<(Pubkey, AccountSharedData)>> {
|
||||||
optimize_filters(&mut filters);
|
optimize_filters(&mut filters);
|
||||||
let filter_closure = |account: &AccountSharedData| {
|
let filter_closure = |account: &AccountSharedData| {
|
||||||
filters.iter().all(|filter_type| match filter_type {
|
filters
|
||||||
RpcFilterType::DataSize(size) => account.data().len() as u64 == *size,
|
.iter()
|
||||||
RpcFilterType::Memcmp(compare) => compare.bytes_match(account.data()),
|
.all(|filter_type| filter_type.allows(account))
|
||||||
})
|
|
||||||
};
|
};
|
||||||
if self
|
if self
|
||||||
.config
|
.config
|
||||||
|
@ -1954,9 +1953,7 @@ impl JsonRpcRequestProcessor {
|
||||||
// later updates. We include the redundant filters here to avoid returning these accounts.
|
// later updates. We include the redundant filters here to avoid returning these accounts.
|
||||||
//
|
//
|
||||||
// Filter on Token Account state
|
// Filter on Token Account state
|
||||||
filters.push(RpcFilterType::DataSize(
|
filters.push(RpcFilterType::TokenAccountState);
|
||||||
TokenAccount::get_packed_len() as u64
|
|
||||||
));
|
|
||||||
// Filter on Owner address
|
// Filter on Owner address
|
||||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||||
offset: SPL_TOKEN_ACCOUNT_OWNER_OFFSET,
|
offset: SPL_TOKEN_ACCOUNT_OWNER_OFFSET,
|
||||||
|
@ -1979,14 +1976,9 @@ impl JsonRpcRequestProcessor {
|
||||||
&IndexKey::SplTokenOwner(*owner_key),
|
&IndexKey::SplTokenOwner(*owner_key),
|
||||||
|account| {
|
|account| {
|
||||||
account.owner() == program_id
|
account.owner() == program_id
|
||||||
&& filters.iter().all(|filter_type| match filter_type {
|
&& filters
|
||||||
RpcFilterType::DataSize(size) => {
|
.iter()
|
||||||
account.data().len() as u64 == *size
|
.all(|filter_type| filter_type.allows(account))
|
||||||
}
|
|
||||||
RpcFilterType::Memcmp(compare) => {
|
|
||||||
compare.bytes_match(account.data())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
&ScanConfig::default(),
|
&ScanConfig::default(),
|
||||||
bank.byte_limit_for_scans(),
|
bank.byte_limit_for_scans(),
|
||||||
|
@ -2013,9 +2005,7 @@ impl JsonRpcRequestProcessor {
|
||||||
// updates. We include the redundant filters here to avoid returning these accounts.
|
// updates. We include the redundant filters here to avoid returning these accounts.
|
||||||
//
|
//
|
||||||
// Filter on Token Account state
|
// Filter on Token Account state
|
||||||
filters.push(RpcFilterType::DataSize(
|
filters.push(RpcFilterType::TokenAccountState);
|
||||||
TokenAccount::get_packed_len() as u64
|
|
||||||
));
|
|
||||||
// Filter on Mint address
|
// Filter on Mint address
|
||||||
filters.push(RpcFilterType::Memcmp(Memcmp {
|
filters.push(RpcFilterType::Memcmp(Memcmp {
|
||||||
offset: SPL_TOKEN_ACCOUNT_MINT_OFFSET,
|
offset: SPL_TOKEN_ACCOUNT_MINT_OFFSET,
|
||||||
|
@ -2037,14 +2027,9 @@ impl JsonRpcRequestProcessor {
|
||||||
&IndexKey::SplTokenMint(*mint_key),
|
&IndexKey::SplTokenMint(*mint_key),
|
||||||
|account| {
|
|account| {
|
||||||
account.owner() == program_id
|
account.owner() == program_id
|
||||||
&& filters.iter().all(|filter_type| match filter_type {
|
&& filters
|
||||||
RpcFilterType::DataSize(size) => {
|
.iter()
|
||||||
account.data().len() as u64 == *size
|
.all(|filter_type| filter_type.allows(account))
|
||||||
}
|
|
||||||
RpcFilterType::Memcmp(compare) => {
|
|
||||||
compare.bytes_match(account.data())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
&ScanConfig::default(),
|
&ScanConfig::default(),
|
||||||
bank.byte_limit_for_scans(),
|
bank.byte_limit_for_scans(),
|
||||||
|
|
|
@ -15,14 +15,11 @@ use {
|
||||||
rayon::prelude::*,
|
rayon::prelude::*,
|
||||||
serde::Serialize,
|
serde::Serialize,
|
||||||
solana_account_decoder::{parse_token::is_known_spl_token_id, UiAccount, UiAccountEncoding},
|
solana_account_decoder::{parse_token::is_known_spl_token_id, UiAccount, UiAccountEncoding},
|
||||||
solana_client::{
|
solana_client::rpc_response::{
|
||||||
rpc_filter::RpcFilterType,
|
|
||||||
rpc_response::{
|
|
||||||
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcBlockUpdate,
|
ProcessedSignatureResult, ReceivedSignatureResult, Response, RpcBlockUpdate,
|
||||||
RpcBlockUpdateError, RpcKeyedAccount, RpcLogsResponse, RpcResponseContext,
|
RpcBlockUpdateError, RpcKeyedAccount, RpcLogsResponse, RpcResponseContext,
|
||||||
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
RpcSignatureResult, RpcVote, SlotInfo, SlotUpdate,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path},
|
solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_rayon_threadlimit::get_thread_count,
|
solana_rayon_threadlimit::get_thread_count,
|
||||||
|
@ -400,10 +397,9 @@ fn filter_program_results(
|
||||||
let encoding = params.encoding;
|
let encoding = params.encoding;
|
||||||
let filters = params.filters.clone();
|
let filters = params.filters.clone();
|
||||||
let keyed_accounts = accounts.into_iter().filter(move |(_, account)| {
|
let keyed_accounts = accounts.into_iter().filter(move |(_, account)| {
|
||||||
filters.iter().all(|filter_type| match filter_type {
|
filters
|
||||||
RpcFilterType::DataSize(size) => account.data().len() as u64 == *size,
|
.iter()
|
||||||
RpcFilterType::Memcmp(compare) => compare.bytes_match(account.data()),
|
.all(|filter_type| filter_type.allows(account))
|
||||||
})
|
|
||||||
});
|
});
|
||||||
let accounts: Box<dyn Iterator<Item = RpcKeyedAccount>> =
|
let accounts: Box<dyn Iterator<Item = RpcKeyedAccount>> =
|
||||||
if is_known_spl_token_id(¶ms.pubkey)
|
if is_known_spl_token_id(¶ms.pubkey)
|
||||||
|
|
Loading…
Reference in New Issue