use crate::*;
#[derive(Clone)]
pub struct ServiceRowWithData {
pub service: Pubkey,
pub service_account: FunctionServiceAccountData,
pub function: Pubkey,
pub function_account: FunctionAccountData,
}
impl ServiceWorkerAccountData {
pub fn fetch(
client: &solana_client::rpc_client::RpcClient,
pubkey: Pubkey,
) -> std::result::Result<Self, switchboard_common::SbError> {
crate::client::fetch_zerocopy_account(client, pubkey)
}
pub async fn fetch_async(
client: &solana_client::nonblocking::rpc_client::RpcClient,
pubkey: Pubkey,
) -> std::result::Result<Self, switchboard_common::SbError> {
crate::client::fetch_zerocopy_account_async(client, pubkey).await
}
pub fn fetch_sync<T: solana_sdk::client::SyncClient>(
client: &T,
pubkey: Pubkey,
) -> std::result::Result<Self, switchboard_common::SbError> {
crate::client::fetch_zerocopy_account_sync(client, pubkey)
}
pub async fn fetch_services(
&self,
client: &solana_client::nonblocking::rpc_client::RpcClient,
) -> std::result::Result<Vec<ServiceRowWithData>, switchboard_common::SbError> {
let rows = &self.services[..self.services_len as usize];
let mut service_pubkeys: Vec<Pubkey> = vec![];
let mut function_pubkeys: Vec<Pubkey> = vec![];
for row in rows {
service_pubkeys.push(row.service);
function_pubkeys.push(row.function);
}
let all_pubkeys: Vec<Pubkey> = [service_pubkeys.clone(), function_pubkeys.clone()].concat();
let accounts: Vec<Option<solana_sdk::account::Account>> =
match client.get_multiple_accounts(&all_pubkeys).await {
Err(e) => {
log::error!("Error fetching accounts: {:?}", e);
return Err(switchboard_common::SbError::CustomError {
message: "Failed to call getProgramAccounts".to_string(),
source: std::sync::Arc::new(e),
});
}
Ok(accounts) => accounts,
};
let mut services: Vec<ServiceRowWithData> = Vec::with_capacity(rows.len());
for i in 0..rows.len() {
let service_pubkey = service_pubkeys[i];
let service_account = match accounts[i].clone() {
None => {
log::error!("Error fetching service account {:?}", service_pubkey);
continue;
}
Some(account) => {
match FunctionServiceAccountData::try_deserialize(&mut &account.data[..]) {
Ok(service) => service,
Err(e) => {
log::error!(
"Error deseserializing service account {:?}: {:?}",
service_pubkey,
e
);
continue;
}
}
}
};
let function_pubkey = function_pubkeys[i];
let function_account = match accounts[i + rows.len()].clone() {
None => {
log::error!("Error fetching function account {:?}", function_pubkey);
continue;
}
Some(account) => {
match FunctionAccountData::try_deserialize(&mut &account.data[..]) {
Ok(function) => function,
Err(e) => {
log::error!(
"Error deseserializing function account {:?}: {:?}",
function_pubkey,
e
);
continue;
}
}
}
};
services[i] = ServiceRowWithData {
service: service_pubkey,
service_account,
function: function_pubkey,
function_account,
};
}
Ok(services)
}
}