Merge pull request #2 from blockworks-foundation/aggregate_stake

test sysvar account prg
This commit is contained in:
Philippe Delrieu 2023-11-07 14:46:23 +01:00 committed by GitHub
commit f9b3e979c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 67 additions and 33 deletions

View File

@ -1,6 +1,9 @@
use solana_sdk::commitment_config::CommitmentConfig;
use anyhow::bail; use anyhow::bail;
use futures_util::StreamExt; use futures_util::StreamExt;
use solana_client::client_error::ClientError;
use solana_client::rpc_client::RpcClient;
use solana_client::rpc_response::Response;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
use std::collections::HashMap; use std::collections::HashMap;
use yellowstone_grpc_client::GeyserGrpcClient; use yellowstone_grpc_client::GeyserGrpcClient;
@ -10,12 +13,11 @@ use yellowstone_grpc_proto::{
prelude::{subscribe_update::UpdateOneof, SubscribeRequestFilterSlots}, prelude::{subscribe_update::UpdateOneof, SubscribeRequestFilterSlots},
tonic::service::Interceptor, tonic::service::Interceptor,
}; };
use solana_client::rpc_response::Response;
use solana_client::client_error::ClientError;
use solana_client::rpc_client::RpcClient;
const GRPC_URL: &str = "http://localhost:10000"; //const GRPC_URL: &str = "http://localhost:10000";
const RPC_URL: &str = "http://localhost:8899"; //const RPC_URL: &str = "http://localhost:8899";
const GRPC_URL: &str = "http://147.28.169.13:10000";
const RPC_URL: &str = "http://147.28.169.13:8899";
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
@ -28,8 +30,26 @@ async fn main() -> anyhow::Result<()> {
let ctrl_c_signal = tokio::signal::ctrl_c(); let ctrl_c_signal = tokio::signal::ctrl_c();
let sysvar_account_list = [
(solana_sdk::sysvar::clock::ID, "Clock"),
(solana_sdk::sysvar::epoch_schedule::ID, "Epoch Schedule"),
(solana_sdk::sysvar::fees::ID, "Fee"),
(solana_sdk::sysvar::instructions::ID, "Instructions"),
(
solana_sdk::sysvar::recent_blockhashes::ID,
"Recent Blockhashes",
),
(solana_sdk::sysvar::rent::ID, "Rent"),
(solana_sdk::sysvar::rewards::ID, "Rewards"),
(solana_sdk::sysvar::slot_hashes::ID, "Slot Hashes"),
(solana_sdk::sysvar::slot_history::ID, "Slot History"),
(solana_sdk::sysvar::stake_history::ID, "Stake history"),
];
load_accounts_from_rpc(&sysvar_account_list);
tokio::select! { tokio::select! {
res = run_loop(client) => { res = run_loop(client, &sysvar_account_list) => {
// This should never happen // This should never happen
log::error!("Services quit unexpectedly {res:?}"); log::error!("Services quit unexpectedly {res:?}");
} }
@ -41,29 +61,32 @@ async fn main() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Result<()> { async fn run_loop<F: Interceptor>(
mut client: GeyserGrpcClient<F>,
accounts: &[(Pubkey, &str)],
) -> anyhow::Result<()> {
//subscribe Geyser grpc //subscribe Geyser grpc
//slot subscription //slot subscription
let mut slots = HashMap::new(); let mut slots = HashMap::new();
slots.insert("client".to_string(), SubscribeRequestFilterSlots {}); slots.insert("client".to_string(), SubscribeRequestFilterSlots {});
//account subscription //account subscription
let mut accounts: HashMap<String, SubscribeRequestFilterAccounts> = HashMap::new(); let mut accounts_filter: HashMap<String, SubscribeRequestFilterAccounts> = HashMap::new();
accounts.insert( for (id, _) in accounts {
accounts_filter.insert(
"client".to_owned(), "client".to_owned(),
SubscribeRequestFilterAccounts { SubscribeRequestFilterAccounts {
account: vec![], account: vec![],
owner: vec![ owner: vec![id.to_string()],
solana_sdk::sysvar::stake_history::ID.to_string(),
],
filters: vec![], filters: vec![],
}, },
); );
}
let mut confirmed_stream = client let mut confirmed_stream = client
.subscribe_once( .subscribe_once(
slots.clone(), slots.clone(),
accounts.clone(), //accounts accounts_filter, //accounts
Default::default(), //tx Default::default(), //tx
Default::default(), //entry Default::default(), //entry
Default::default(), //full block Default::default(), //full block
@ -78,11 +101,15 @@ async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Re
Some(UpdateOneof::Account(account)) => { Some(UpdateOneof::Account(account)) => {
if let Some(account) = account.account { if let Some(account) = account.account {
let owner = Pubkey::try_from(account.owner).expect("valid pubkey"); let owner = Pubkey::try_from(account.owner).expect("valid pubkey");
match owner { log::info!("Geyser notif for account account:{:?}", owner);
solana_sdk::sysvar::stake_history::ID => {
log::info!("Geyser notif Stake History account:{:?}", owner); match accounts.iter().filter(|(id, _)| *id == owner).next() {
Some((_, name)) => {
log::info!("Geyser receive notification for account:{name}")
} }
_ => log::warn!("receive an account notification from a unknown owner:{owner:?}"), None => log::warn!(
"Geyser receive a notification from a unknown account:{owner}"
),
} }
} }
} }
@ -96,15 +123,22 @@ async fn run_loop<F: Interceptor>(mut client: GeyserGrpcClient<F>) -> anyhow::Re
}; };
} }
Ok(()) Ok(())
} }
fn load_account_from_rpc() { fn load_accounts_from_rpc(accounts: &[(Pubkey, &str)]) {
let rpc_client = RpcClient::new(RPC_URL); let rpc_client = RpcClient::new(RPC_URL);
match rpc_client.get_account_with_commitment(&solana_sdk::sysvar::stake_history::id(), CommitmentConfig::confirmed()) { for (id, name) in accounts {
Ok(Response { context: Some(_), .. }) => log::info!("RPC get_account return the stake history account"), load_account_from_rpc(*id, name, &rpc_client);
Ok(Response { context: None, .. }) => log::info!("RPC get_account doesn't find the stake history account"), }
Err(_) => log::error!("Error during RPC call:{err}") }
fn load_account_from_rpc(id: Pubkey, name: &str, rpc_client: &RpcClient) {
match rpc_client.get_account_with_commitment(&id, CommitmentConfig::confirmed()) {
Ok(Response { value: Some(_), .. }) => {
log::info!("RPC get_account return the {name} account")
}
Ok(Response { value: None, .. }) => {
log::info!("RPC get_account doesn't find the {name} account")
}
Err(err) => log::error!("Error during RPC call:{err}"),
} }
} }