|
|
|
@ -10,7 +10,7 @@ use {
|
|
|
|
|
jsonrpc_derive::rpc,
|
|
|
|
|
serde::{Deserialize, Serialize},
|
|
|
|
|
solana_account_decoder::{
|
|
|
|
|
parse_token::{spl_token_id_v2_0, token_amount_to_ui_amount, UiTokenAmount},
|
|
|
|
|
parse_token::{spl_token_id, token_amount_to_ui_amount, UiTokenAmount},
|
|
|
|
|
UiAccount, UiAccountEncoding, UiDataSliceConfig, MAX_BASE58_BYTES,
|
|
|
|
|
},
|
|
|
|
|
solana_client::{
|
|
|
|
@ -43,7 +43,7 @@ use {
|
|
|
|
|
bank::{Bank, TransactionSimulationResult},
|
|
|
|
|
bank_forks::BankForks,
|
|
|
|
|
commitment::{BlockCommitmentArray, BlockCommitmentCache, CommitmentSlots},
|
|
|
|
|
inline_spl_token_v2_0::{SPL_TOKEN_ACCOUNT_MINT_OFFSET, SPL_TOKEN_ACCOUNT_OWNER_OFFSET},
|
|
|
|
|
inline_spl_token::{SPL_TOKEN_ACCOUNT_MINT_OFFSET, SPL_TOKEN_ACCOUNT_OWNER_OFFSET},
|
|
|
|
|
non_circulating_supply::calculate_non_circulating_supply,
|
|
|
|
|
snapshot_config::SnapshotConfig,
|
|
|
|
|
snapshot_utils,
|
|
|
|
@ -78,7 +78,7 @@ use {
|
|
|
|
|
TransactionConfirmationStatus, TransactionStatus, UiConfirmedBlock, UiTransactionEncoding,
|
|
|
|
|
},
|
|
|
|
|
solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY},
|
|
|
|
|
spl_token_v2_0::{
|
|
|
|
|
spl_token::{
|
|
|
|
|
solana_program::program_pack::Pack,
|
|
|
|
|
state::{Account as TokenAccount, Mint},
|
|
|
|
|
},
|
|
|
|
@ -396,9 +396,7 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
self.get_filtered_program_accounts(&bank, program_id, filters)?
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
let result = if program_id == &spl_token_id_v2_0()
|
|
|
|
|
&& encoding == UiAccountEncoding::JsonParsed
|
|
|
|
|
{
|
|
|
|
|
let result = if program_id == &spl_token_id() && encoding == UiAccountEncoding::JsonParsed {
|
|
|
|
|
get_parsed_token_accounts(bank.clone(), keyed_accounts.into_iter()).collect()
|
|
|
|
|
} else {
|
|
|
|
|
keyed_accounts
|
|
|
|
@ -1628,14 +1626,13 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
Error::invalid_params("Invalid param: could not find account".to_string())
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
if account.owner() != &spl_token_id_v2_0() {
|
|
|
|
|
if account.owner() != &spl_token_id() {
|
|
|
|
|
return Err(Error::invalid_params(
|
|
|
|
|
"Invalid param: not a v2.0 Token account".to_string(),
|
|
|
|
|
"Invalid param: not a Token account".to_string(),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let token_account = TokenAccount::unpack(account.data()).map_err(|_| {
|
|
|
|
|
Error::invalid_params("Invalid param: not a v2.0 Token account".to_string())
|
|
|
|
|
})?;
|
|
|
|
|
let token_account = TokenAccount::unpack(account.data())
|
|
|
|
|
.map_err(|_| Error::invalid_params("Invalid param: not a Token account".to_string()))?;
|
|
|
|
|
let mint = &Pubkey::from_str(&token_account.mint.to_string())
|
|
|
|
|
.expect("Token account mint should be convertible to Pubkey");
|
|
|
|
|
let (_, decimals) = get_mint_owner_and_decimals(&bank, mint)?;
|
|
|
|
@ -1652,9 +1649,9 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
let mint_account = bank.get_account(mint).ok_or_else(|| {
|
|
|
|
|
Error::invalid_params("Invalid param: could not find account".to_string())
|
|
|
|
|
})?;
|
|
|
|
|
if mint_account.owner() != &spl_token_id_v2_0() {
|
|
|
|
|
if mint_account.owner() != &spl_token_id() {
|
|
|
|
|
return Err(Error::invalid_params(
|
|
|
|
|
"Invalid param: not a v2.0 Token mint".to_string(),
|
|
|
|
|
"Invalid param: not a Token mint".to_string(),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let mint = Mint::unpack(mint_account.data()).map_err(|_| {
|
|
|
|
@ -1672,9 +1669,9 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
) -> Result<RpcResponse<Vec<RpcTokenAccountBalance>>> {
|
|
|
|
|
let bank = self.bank(commitment);
|
|
|
|
|
let (mint_owner, decimals) = get_mint_owner_and_decimals(&bank, mint)?;
|
|
|
|
|
if mint_owner != spl_token_id_v2_0() {
|
|
|
|
|
if mint_owner != spl_token_id() {
|
|
|
|
|
return Err(Error::invalid_params(
|
|
|
|
|
"Invalid param: not a v2.0 Token mint".to_string(),
|
|
|
|
|
"Invalid param: not a Token mint".to_string(),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let mut token_balances: Vec<RpcTokenAccountBalance> = self
|
|
|
|
@ -1893,7 +1890,7 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
.get_filtered_indexed_accounts(
|
|
|
|
|
&IndexKey::SplTokenOwner(*owner_key),
|
|
|
|
|
|account| {
|
|
|
|
|
account.owner() == &spl_token_id_v2_0()
|
|
|
|
|
account.owner() == &spl_token_id()
|
|
|
|
|
&& filters.iter().all(|filter_type| match filter_type {
|
|
|
|
|
RpcFilterType::DataSize(size) => {
|
|
|
|
|
account.data().len() as u64 == *size
|
|
|
|
@ -1910,7 +1907,7 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
message: e.to_string(),
|
|
|
|
|
})?)
|
|
|
|
|
} else {
|
|
|
|
|
self.get_filtered_program_accounts(bank, &spl_token_id_v2_0(), filters)
|
|
|
|
|
self.get_filtered_program_accounts(bank, &spl_token_id(), filters)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1950,7 +1947,7 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
.get_filtered_indexed_accounts(
|
|
|
|
|
&IndexKey::SplTokenMint(*mint_key),
|
|
|
|
|
|account| {
|
|
|
|
|
account.owner() == &spl_token_id_v2_0()
|
|
|
|
|
account.owner() == &spl_token_id()
|
|
|
|
|
&& filters.iter().all(|filter_type| match filter_type {
|
|
|
|
|
RpcFilterType::DataSize(size) => {
|
|
|
|
|
account.data().len() as u64 == *size
|
|
|
|
@ -1967,7 +1964,7 @@ impl JsonRpcRequestProcessor {
|
|
|
|
|
message: e.to_string(),
|
|
|
|
|
})?)
|
|
|
|
|
} else {
|
|
|
|
|
self.get_filtered_program_accounts(bank, &spl_token_id_v2_0(), filters)
|
|
|
|
|
self.get_filtered_program_accounts(bank, &spl_token_id(), filters)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2149,7 +2146,7 @@ fn get_encoded_account(
|
|
|
|
|
) -> Result<Option<UiAccount>> {
|
|
|
|
|
match bank.get_account(pubkey) {
|
|
|
|
|
Some(account) => {
|
|
|
|
|
let response = if account.owner() == &spl_token_id_v2_0()
|
|
|
|
|
let response = if account.owner() == &spl_token_id()
|
|
|
|
|
&& encoding == UiAccountEncoding::JsonParsed
|
|
|
|
|
{
|
|
|
|
|
get_parsed_token_account(bank.clone(), pubkey, account)
|
|
|
|
@ -2189,7 +2186,7 @@ fn encode_account<T: ReadableAccount>(
|
|
|
|
|
/// NOTE: `optimize_filters()` should almost always be called before using this method because of
|
|
|
|
|
/// the strict match on `MemcmpEncodedBytes::Bytes`.
|
|
|
|
|
fn get_spl_token_owner_filter(program_id: &Pubkey, filters: &[RpcFilterType]) -> Option<Pubkey> {
|
|
|
|
|
if program_id != &spl_token_id_v2_0() {
|
|
|
|
|
if program_id != &spl_token_id() {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
let mut data_size_filter: Option<u64> = None;
|
|
|
|
@ -2231,7 +2228,7 @@ fn get_spl_token_owner_filter(program_id: &Pubkey, filters: &[RpcFilterType]) ->
|
|
|
|
|
/// NOTE: `optimize_filters()` should almost always be called before using this method because of
|
|
|
|
|
/// the strict match on `MemcmpEncodedBytes::Bytes`.
|
|
|
|
|
fn get_spl_token_mint_filter(program_id: &Pubkey, filters: &[RpcFilterType]) -> Option<Pubkey> {
|
|
|
|
|
if program_id != &spl_token_id_v2_0() {
|
|
|
|
|
if program_id != &spl_token_id() {
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
let mut data_size_filter: Option<u64> = None;
|
|
|
|
@ -2277,15 +2274,15 @@ fn get_token_program_id_and_mint(
|
|
|
|
|
match token_account_filter {
|
|
|
|
|
TokenAccountsFilter::Mint(mint) => {
|
|
|
|
|
let (mint_owner, _) = get_mint_owner_and_decimals(bank, &mint)?;
|
|
|
|
|
if mint_owner != spl_token_id_v2_0() {
|
|
|
|
|
if mint_owner != spl_token_id() {
|
|
|
|
|
return Err(Error::invalid_params(
|
|
|
|
|
"Invalid param: not a v2.0 Token mint".to_string(),
|
|
|
|
|
"Invalid param: not a Token mint".to_string(),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
Ok((mint_owner, Some(mint)))
|
|
|
|
|
}
|
|
|
|
|
TokenAccountsFilter::ProgramId(program_id) => {
|
|
|
|
|
if program_id == spl_token_id_v2_0() {
|
|
|
|
|
if program_id == spl_token_id() {
|
|
|
|
|
Ok((program_id, None))
|
|
|
|
|
} else {
|
|
|
|
|
Err(Error::invalid_params(
|
|
|
|
@ -4337,7 +4334,7 @@ pub mod tests {
|
|
|
|
|
vote_instruction,
|
|
|
|
|
vote_state::{BlockTimestamp, Vote, VoteInit, VoteStateVersions, MAX_LOCKOUT_HISTORY},
|
|
|
|
|
},
|
|
|
|
|
spl_token_v2_0::{
|
|
|
|
|
spl_token::{
|
|
|
|
|
solana_program::{program_option::COption, pubkey::Pubkey as SplTokenPubkey},
|
|
|
|
|
state::AccountState as TokenAccountState,
|
|
|
|
|
state::Mint,
|
|
|
|
@ -7232,7 +7229,7 @@ pub mod tests {
|
|
|
|
|
let token_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: account_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
let token_account_pubkey = solana_sdk::pubkey::new_rand();
|
|
|
|
@ -7251,7 +7248,7 @@ pub mod tests {
|
|
|
|
|
let mint_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: mint_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
bank.store_account(&Pubkey::from_str(&mint.to_string()).unwrap(), &mint_account);
|
|
|
|
@ -7328,7 +7325,7 @@ pub mod tests {
|
|
|
|
|
let token_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: account_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
let token_with_different_mint_pubkey = solana_sdk::pubkey::new_rand();
|
|
|
|
@ -7343,7 +7340,7 @@ pub mod tests {
|
|
|
|
|
"params":["{}", {{"programId": "{}"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
owner,
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7361,7 +7358,7 @@ pub mod tests {
|
|
|
|
|
"params":["{}", {{"programId": "{}"}}, {{"encoding": "jsonParsed"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
owner,
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7378,7 +7375,7 @@ pub mod tests {
|
|
|
|
|
"method":"getProgramAccounts",
|
|
|
|
|
"params":["{}", {{"encoding": "jsonParsed"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7442,7 +7439,7 @@ pub mod tests {
|
|
|
|
|
"params":["{}", {{"programId": "{}"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
solana_sdk::pubkey::new_rand(),
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7460,7 +7457,7 @@ pub mod tests {
|
|
|
|
|
"params":["{}", {{"programId": "{}"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
delegate,
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7525,7 +7522,7 @@ pub mod tests {
|
|
|
|
|
"params":["{}", {{"programId": "{}"}}]
|
|
|
|
|
}}"#,
|
|
|
|
|
solana_sdk::pubkey::new_rand(),
|
|
|
|
|
spl_token_id_v2_0(),
|
|
|
|
|
spl_token_id(),
|
|
|
|
|
);
|
|
|
|
|
let res = io.handle_request_sync(&req, meta.clone());
|
|
|
|
|
let result: Value = serde_json::from_str(&res.expect("actual response"))
|
|
|
|
@ -7547,7 +7544,7 @@ pub mod tests {
|
|
|
|
|
let mint_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: mint_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
bank.store_account(
|
|
|
|
@ -7569,7 +7566,7 @@ pub mod tests {
|
|
|
|
|
let token_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: account_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
let token_with_smaller_balance = solana_sdk::pubkey::new_rand();
|
|
|
|
@ -7633,7 +7630,7 @@ pub mod tests {
|
|
|
|
|
let token_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: account_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
let token_account_pubkey = solana_sdk::pubkey::new_rand();
|
|
|
|
@ -7652,7 +7649,7 @@ pub mod tests {
|
|
|
|
|
let mint_account = AccountSharedData::from(Account {
|
|
|
|
|
lamports: 111,
|
|
|
|
|
data: mint_data.to_vec(),
|
|
|
|
|
owner: spl_token_id_v2_0(),
|
|
|
|
|
owner: spl_token_id(),
|
|
|
|
|
..Account::default()
|
|
|
|
|
});
|
|
|
|
|
bank.store_account(&Pubkey::from_str(&mint.to_string()).unwrap(), &mint_account);
|
|
|
|
|