geyser_gpa/
lib.rs

1use std::slice::Iter;
2use std::str::FromStr;
3// use fred::prelude::*;
4// use fred::prelude::ServerConfig::Centralized;
5// use fred::types::{RespVersion, Server};
6use solana_client::{
7    rpc_filter::{RpcFilterType }, // Memcmp, MemcmpEncodedBytes, MemcmpEncoding},
8    rpc_config::{RpcProgramAccountsConfig, RpcAccountInfoConfig},
9};
10use redis::{Client as RedisClient, Commands, Connection};
11use solana_program::pubkey::Pubkey;
12
13
14fn filter_account(data: &[u8], filters: &Vec<RpcFilterType>) -> bool {
15    for item in filters.iter() {
16        match item {
17            RpcFilterType::Memcmp(memcmp) => {
18                let result = memcmp.bytes_match(data);
19                if !result {
20                    return false;
21                }
22            }
23            RpcFilterType::DataSize(x) => {
24                if *x != data.len() as u64 {
25                    return false
26                }
27            }
28            _ => {}
29        }
30    }
31    return true;
32}
33
34pub struct Client {
35    connection: Connection,
36}
37
38pub fn new() -> Client {
39    let redis_client = RedisClient::open("redis://127.0.0.1/").unwrap();
40    let connection = redis_client.get_connection().unwrap();
41
42    // let redis_client = RedisClient::new(RedisConfig{
43    //     fail_fast: false,
44    //     blocking: Blocking::Interrupt,
45    //     username: None,
46    //     password: None,
47    //     server: Centralized{
48    //         server: Server {
49    //             host: "localhost".parse().unwrap(),
50    //             port: 6379,
51    //             tls_server_name: None
52    //         }
53    //     },
54    //     version: RespVersion::RESP2,
55    //     database: Some(0),
56    // }, Some(PerformanceConfig::default()), Some(ReconnectPolicy::default()));
57    return Client{ connection};
58}
59
60impl Client {
61    pub fn get_program_accounts(
62        &mut self,
63        pubkey: &Pubkey
64    ) -> Vec<(Pubkey, Vec<u8>)>{
65        let keys_result = self.connection.keys::<String,Vec<String>>(pubkey.to_string() + "*").unwrap();
66        let mut result = redis::cmd("MGET")
67            .arg(&keys_result).query::<Vec<Vec<u8>>>(&mut self.connection).unwrap();
68        let keys = keys_result.iter().map(|key| key.to_string().split(":").collect::<Vec<&str>>()[1].to_string() ).collect::<Vec<String>>();
69        let mut final_result = vec![];
70        for idx in keys.len()..0 {
71            let data = result.pop().unwrap();
72            final_result.push((Pubkey::from_str(&keys[idx]).unwrap(), data));
73        }
74        return final_result;
75    }
76
77    pub fn  get_program_accounts_with_config(
78        &mut self,
79        pubkey: &Pubkey,
80        config: RpcProgramAccountsConfig,
81    ) -> Vec<(Pubkey, Vec<u8>)> {
82        let filters = config.filters.unwrap();
83        let keys_result = self.connection.keys::<String,Vec<String>>(pubkey.to_string() + "*").unwrap();
84        let mut result = redis::cmd("MGET")
85            .arg(&keys_result).query::<Vec<Vec<u8>>>(&mut self.connection).unwrap();
86        let keys = keys_result.iter().map(|key| key.to_string().split(":").collect::<Vec<&str>>()[1].to_string() ).collect::<Vec<String>>();
87        let mut final_result = vec![];
88        for idx in keys.len()..0 {
89            let data = result.pop().unwrap();
90            if filter_account(&data, &filters) {
91                final_result.push((Pubkey::from_str(&keys[idx]).unwrap(), data));
92            }
93        }
94        return final_result;
95    }
96
97}