Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion external/photon
103 changes: 100 additions & 3 deletions sdk-libs/client/src/indexer/types/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ pub struct AccountInterface {
}

impl AccountInterface {
/// Returns true if this account is on-chain (hot)
/// Returns true if this account is on-chain (hot).
pub fn is_hot(&self) -> bool {
self.cold.is_none()
}

/// Returns true if this account is compressed (cold)
/// Returns true if this account is compressed (cold).
pub fn is_cold(&self) -> bool {
self.cold.is_some()
}
Expand All @@ -128,7 +128,6 @@ impl AccountInterface {
fn convert_account_interface(
ai: &photon_api::types::AccountInterface,
) -> Result<AccountInterface, IndexerError> {
// Take the first compressed account entry if present
let cold = ai
.cold
.as_ref()
Expand Down Expand Up @@ -168,3 +167,101 @@ pub struct TokenAccountInterface {
/// Parsed token data (same as CompressedTokenAccount.token)
pub token: TokenData,
}

#[cfg(test)]
mod tests {
use super::*;

fn default_tree_info() -> InterfaceTreeInfo {
InterfaceTreeInfo {
tree: Pubkey::default(),
queue: Pubkey::default(),
tree_type: TreeType::StateV2,
seq: Some(1),
slot_created: 100,
}
}

fn make_cold_context(discriminator: [u8; 8]) -> ColdContext {
ColdContext {
hash: [1u8; 32],
leaf_index: 0,
tree_info: default_tree_info(),
data: ColdData {
discriminator,
data: vec![1, 2, 3],
data_hash: [2u8; 32],
},
address: Some([3u8; 32]),
prove_by_index: false,
}
}

fn make_account(lamports: u64) -> SolanaAccountData {
Account {
lamports,
data: vec![],
owner: Pubkey::default(),
executable: false,
rent_epoch: 0,
}
}

#[test]
fn test_pure_on_chain_is_hot() {
let ai = AccountInterface {
key: Pubkey::new_unique(),
account: make_account(1_000_000),
cold: None,
};
assert!(ai.is_hot());
assert!(!ai.is_cold());
}

#[test]
fn test_compressed_is_cold() {
let ai = AccountInterface {
key: Pubkey::new_unique(),
account: make_account(0),
cold: Some(make_cold_context([1, 2, 3, 4, 5, 6, 7, 8])),
};
assert!(ai.is_cold());
assert!(!ai.is_hot());
}

#[test]
fn test_zero_discriminator_is_cold() {
let ai = AccountInterface {
key: Pubkey::new_unique(),
account: make_account(0),
cold: Some(make_cold_context([0u8; 8])),
};
assert!(ai.is_cold());
assert!(!ai.is_hot());
}

#[test]
fn test_token_account_interface_delegates_is_cold() {
let token = TokenData::default();

let cold_tai = TokenAccountInterface {
account: AccountInterface {
key: Pubkey::new_unique(),
account: make_account(0),
cold: Some(make_cold_context([1, 2, 3, 4, 5, 6, 7, 8])),
},
token: token.clone(),
};
assert!(cold_tai.account.is_cold());

let hot_tai = TokenAccountInterface {
account: AccountInterface {
key: Pubkey::new_unique(),
account: make_account(1_000_000),
cold: None,
},
token,
};
assert!(hot_tai.account.is_hot());
}
}
40 changes: 21 additions & 19 deletions sdk-libs/client/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,16 +540,7 @@ fn cold_context_to_compressed_account(
fn convert_account_interface(
indexer_ai: IndexerAccountInterface,
) -> Result<AccountInterface, RpcError> {
let account = Account {
lamports: indexer_ai.account.lamports,
data: indexer_ai.account.data,
owner: indexer_ai.account.owner,
executable: indexer_ai.account.executable,
rent_epoch: indexer_ai.account.rent_epoch,
};

match indexer_ai.cold {
None => Ok(AccountInterface::hot(indexer_ai.key, account)),
Some(cold) => {
let compressed = cold_context_to_compressed_account(
&cold,
Expand All @@ -562,6 +553,16 @@ fn convert_account_interface(
indexer_ai.account.owner,
))
}
None => {
let account = Account {
lamports: indexer_ai.account.lamports,
data: indexer_ai.account.data,
owner: indexer_ai.account.owner,
executable: indexer_ai.account.executable,
rent_epoch: indexer_ai.account.rent_epoch,
};
Ok(AccountInterface::hot(indexer_ai.key, account))
}
}
}

Expand All @@ -570,17 +571,7 @@ fn convert_token_account_interface(
) -> Result<TokenAccountInterface, RpcError> {
use crate::indexer::CompressedTokenAccount;

let account = Account {
lamports: indexer_tai.account.account.lamports,
data: indexer_tai.account.account.data.clone(),
owner: indexer_tai.account.account.owner,
executable: indexer_tai.account.account.executable,
rent_epoch: indexer_tai.account.account.rent_epoch,
};

match indexer_tai.account.cold {
None => TokenAccountInterface::hot(indexer_tai.account.key, account)
.map_err(|e| RpcError::CustomError(format!("parse error: {}", e))),
Some(cold) => {
let compressed_account = cold_context_to_compressed_account(
&cold,
Expand All @@ -600,6 +591,17 @@ fn convert_token_account_interface(
indexer_tai.account.account.owner,
))
}
None => {
let account = Account {
lamports: indexer_tai.account.account.lamports,
data: indexer_tai.account.account.data,
owner: indexer_tai.account.account.owner,
executable: indexer_tai.account.account.executable,
rent_epoch: indexer_tai.account.account.rent_epoch,
};
TokenAccountInterface::hot(indexer_tai.account.key, account)
.map_err(|e| RpcError::CustomError(format!("parse error: {}", e)))
}
}
}

Expand Down