Skip to content

Commit

Permalink
Adding tests for account filters
Browse files Browse the repository at this point in the history
  • Loading branch information
godmodegalactus committed Feb 13, 2024
1 parent 76607e7 commit 543e39b
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 14 deletions.
16 changes: 12 additions & 4 deletions accounts/src/account_service.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::Arc;
use std::{str::FromStr, sync::Arc};

use anyhow::bail;
use itertools::Itertools;
Expand Down Expand Up @@ -42,10 +42,17 @@ impl AccountService {
let mut accounts = vec![];
for filter in filters.iter() {
if !filter.accounts.is_empty() {
accounts.append(&mut filter.accounts.clone());
let mut f_accounts = filter
.accounts
.iter()
.map(|x| Pubkey::from_str(x).expect("Accounts in filters should be valid"))
.collect();
accounts.append(&mut f_accounts);
}

if let Some(program_id) = filter.program_id {
if let Some(program_id) = &filter.program_id {
let program_id =
Pubkey::from_str(program_id).expect("Program id in filters should be valid");
let mut rpc_acc = rpc_client
.get_program_accounts_with_config(
&program_id,
Expand All @@ -70,7 +77,7 @@ impl AccountService {
accounts.append(&mut rpc_acc);
}
}

log::info!("Fetching {} accounts", accounts.len());
for accounts in accounts.chunks(max_request_in_parallel * NB_ACCOUNTS_IN_GMA) {
for accounts in accounts.chunks(NB_ACCOUNTS_IN_GMA) {
let mut fetch_accounts = vec![];
Expand Down Expand Up @@ -113,6 +120,7 @@ impl AccountService {
}
}
}
log::info!("{} accounts successfully fetched", accounts.len());
Ok(())
}

Expand Down
5 changes: 2 additions & 3 deletions cluster-endpoints/src/grpc/gprc_accounts_streaming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ pub fn configure_account_streaming(
},
);
}
if let Some(program_id) = accounts_filter.program_id {
let program_id = program_id.to_string();
if let Some(program_id) = &accounts_filter.program_id {
let filters = if let Some(filters) = &accounts_filter.filters {
filters
.iter()
Expand Down Expand Up @@ -97,7 +96,7 @@ pub fn configure_account_streaming(
format!("accounts_{}", program_id),
SubscribeRequestFilterAccounts {
account: vec![],
owner: vec![program_id],
owner: vec![program_id.clone()],
filters,
},
);
Expand Down
158 changes: 151 additions & 7 deletions core/src/structures/account_filter.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use solana_rpc_client_api::filter::{Memcmp as RpcMemcmp, MemcmpEncodedBytes, RpcFilterType};
use solana_sdk::pubkey::Pubkey;

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "camelCase")]
pub enum MemcmpFilterData {
Bytes(Vec<u8>),
Base58(String),
Base64(String),
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MemcmpFilter {
pub offset: u64,
pub data: MemcmpFilterData,
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "camelCase")]
pub enum AccountFilterType {
Datasize(u64),
Memcmp(MemcmpFilter),
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct AccountFilter {
pub accounts: Vec<Pubkey>,
pub program_id: Option<Pubkey>,
pub accounts: Vec<String>,
pub program_id: Option<String>,
pub filters: Option<Vec<AccountFilterType>>,
}

Expand Down Expand Up @@ -61,3 +60,148 @@ impl AccountFilter {
}

pub type AccountFilters = Vec<AccountFilter>;

#[test]
fn test_accounts_filters_deserialization() {
let str = "[
{
\"accounts\": [],
\"programId\": \"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg\",
\"filters\": [
{
\"datasize\": 200
}
]
},
{
\"accounts\": [],
\"programId\": \"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg\",
\"filters\": [
{
\"memcmp\": {
\"offset\": 100,
\"data\": {
\"bytes\": [
115,
101,
114,
117,
109,
5,
0,
0,
0,
0,
0,
0,
0
]
}
}
}
]
},
{
\"accounts\": [],
\"programId\": \"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg\"
},
{
\"accounts\": [],
\"programId\": \"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg\",
\"filters\": [
{
\"datasize\": 200
},
{
\"memcmp\": {
\"offset\": 100,
\"data\": {
\"bytes\": [
115,
101,
114,
117,
109,
5,
0,
0,
0,
0,
0,
0,
0
]
}
}
}
]
},
{
\"accounts\": [\"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg\", \"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\"]
}
]
";

let filters: AccountFilters = serde_json::from_str(str).unwrap();

assert_eq!(
filters[0],
AccountFilter {
accounts: vec![],
program_id: Some("4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg".to_string()),
filters: Some(vec![AccountFilterType::Datasize(200)])
}
);

assert_eq!(
filters[1],
AccountFilter {
accounts: vec![],
program_id: Some("4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg".to_string()),
filters: Some(vec![AccountFilterType::Memcmp(MemcmpFilter {
offset: 100,
data: MemcmpFilterData::Bytes(vec![
115, 101, 114, 117, 109, 5, 0, 0, 0, 0, 0, 0, 0
])
})])
}
);

assert_eq!(
filters[2],
AccountFilter {
accounts: vec![],
program_id: Some("4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg".to_string()),
filters: None
}
);

assert_eq!(
filters[3],
AccountFilter {
accounts: vec![],
program_id: Some("4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg".to_string()),
filters: Some(vec![
AccountFilterType::Datasize(200),
AccountFilterType::Memcmp(MemcmpFilter {
offset: 100,
data: MemcmpFilterData::Bytes(vec![
115, 101, 114, 117, 109, 5, 0, 0, 0, 0, 0, 0, 0
])
})
])
}
);

assert_eq!(
filters[4],
AccountFilter {
accounts: vec![
"4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg".to_string(),
"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX".to_string()
],
program_id: None,
filters: None
}
);
}

0 comments on commit 543e39b

Please sign in to comment.